From c8df4971fb75bdf562f47027009353a546987872 Mon Sep 17 00:00:00 2001 From: Manuel Rueda Date: Sun, 21 Sep 2014 16:22:12 -0300 Subject: [PATCH] omitPath new function / grunt lint fixs --- Gruntfile.js | 8 ++--- docs/underscore.object.selectors.js.md | 25 +++++++++++++++ index.html | 21 +++++++++++- test/object.selectors.js | 15 +++++++++ underscore.object.selectors.js | 44 ++++++++++++++++++++++++++ 5 files changed, 108 insertions(+), 5 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 760ff7e..2f64994 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -70,10 +70,10 @@ module.exports = function(grunt) { 'index.html': ['docs/*.md', 'CHANGELOG.md'] }, options: { - scripts: [ - 'test/vendor/underscore.js', - 'dist/underscore-contrib.js' - ] + scripts: [ + 'test/vendor/underscore.js', + 'dist/underscore-contrib.js' + ] } } }, diff --git a/docs/underscore.object.selectors.js.md b/docs/underscore.object.selectors.js.md index 7343bfd..db067bd 100644 --- a/docs/underscore.object.selectors.js.md +++ b/docs/underscore.object.selectors.js.md @@ -182,3 +182,28 @@ var philosopherCities = { _.selectKeys(philosopherCities, ["Plato", "Plotinus"]); // => { Plato: "Athens", Plotinus: "Rome" } ``` + +#### omitPath + +**Signature:** `_.omitPath(obj:Object, ks:String|Array); + +Returns a copy of `obj` excluding the value represented by the `ks` path. +Path may be given as an array or as a dot-separated string. +If the path contains an array, the value of the path will be removed from all the array elements. + +```javascript +var test = { + foo: true, + bar: false, + baz: 42, + dada: { + carlos: { + pepe: 9 + }, + pedro: 'pedro' + } +}; + +_.omitPath(test, 'dada.carlos.pepe'); +// => {foo: true, bar: false, baz: 42, dada: {carlos: {}, pedro: 'pedro'}} +``` diff --git a/index.html b/index.html index 87a570f..dc9e6b2 100644 --- a/index.html +++ b/index.html @@ -10,7 +10,7 @@ -
+

Underscore-contrib (0.3.0)

The brass buckles on Underscore's utility belt - a contributors' library for Underscore.

@@ -1615,6 +1615,25 @@

selectKeys

_.selectKeys(philosopherCities, ["Plato", "Plotinus"]); // => { Plato: "Athens", Plotinus: "Rome" } +

omitPath

+

Signature: `_.omitPath(obj:Object, ks:String|Array);

+

Returns a copy of obj excluding the value represented by the ks path. +Path may be given as an array or as a dot-separated string. +If the path contains an array, the value of the path will be removed from all the array elements.

+
var test = {
+    foo: true, 
+    bar: false, 
+    baz: 42, 
+    dada: {
+        carlos: { 
+            pepe: 9 
+        }, 
+        pedro: 'pedro'
+    }
+};
+
+_.omitPath(test, 'dada.carlos.pepe');
+// => {foo: true, bar: false, baz: 42, dada: {carlos: {}, pedro: 'pedro'}}

util.existential

Functions which deal with whether a value "exists."

diff --git a/test/object.selectors.js b/test/object.selectors.js index 2c57ab0..57de640 100644 --- a/test/object.selectors.js +++ b/test/object.selectors.js @@ -76,4 +76,19 @@ $(document).ready(function() { deepEqual(_.omitWhen(a, _.isEmpty), {baz: "something", quux: ['a']}, "should return an object with kvs that return a falsey value for the given predicate"); }); + + test("omitPath", function(){ + var a = {foo: true, bar: false, baz: 42, dada: {carlos: { pepe: 9 }, pedro: 'pedro', list: [{file: '..', more: {other: { a: 1, b: 2}}, name: 'aa'}, {file: '..', name: 'bb'}]}}; + + deepEqual(_.omitPath(a, 'dada.carlos.pepe'), {foo: true, bar: false, baz: 42, dada: {carlos: {}, pedro: 'pedro', list: [{file: '..', more: {other: { a: 1, b: 2}} , name: 'aa'}, {file: '..', name: 'bb'}]}}, "should return an object without the value that represent the path"); + deepEqual(_.omitPath(a, 'dada.carlos'), {foo: true, bar: false, baz: 42, dada: {pedro: 'pedro', list: [{file: '..', more: {other: { a: 1, b: 2}} , name: 'aa'}, {file: '..', name: 'bb'}]}}, "should return an object without the value that represent the path"); + deepEqual(_.omitPath(a, ''), {foo: true, bar: false, baz: 42, dada: {carlos: { pepe: 9 }, pedro: 'pedro', list: [{file: '..', more: {other: { a: 1, b: 2}} , name: 'aa'}, {file: '..', name: 'bb'}]}}, "should return the whole object because the path is empty"); + + deepEqual(_.omitPath(a, 'dada.list.file'), {foo: true, bar: false, baz: 42, dada: {carlos: { pepe: 9 }, pedro: 'pedro', list: [{name: 'aa', more: {other: { a: 1, b: 2}}}, {name: 'bb'}]}}, "should return an object without the value in each object of the list"); + deepEqual(_.omitPath(a, 'dada.list.name'), {foo: true, bar: false, baz: 42, dada: {carlos: { pepe: 9 }, pedro: 'pedro', list: [{file: '..', more: {other: { a: 1, b: 2}}}, {file: '..'}]}}, "should return an object without the value in each object of the list"); + + deepEqual(_.omitPath(a, 'dada.list'), {foo: true, bar: false, baz: 42, dada: {carlos: { pepe: 9 }, pedro: 'pedro'}}, "should return an object without the list"); + + deepEqual(_.omitPath(a, 'dada.list.more.other.a'), {foo: true, bar: false, baz: 42, dada: {carlos: { pepe: 9 }, pedro: 'pedro', list: [{file: '..', more: {other: { b: 2}} , name: 'aa'}, {file: '..', name: 'bb'}]}}, "should return an object without the value inside the values of the list"); + }); }); diff --git a/underscore.object.selectors.js b/underscore.object.selectors.js index 17308ee..4fcd2fc 100644 --- a/underscore.object.selectors.js +++ b/underscore.object.selectors.js @@ -101,6 +101,50 @@ omitWhen: function(obj, pred) { return _.pickWhen(obj, function(e) { return !pred(e); }); + }, + + // Returns an object excluding the value represented by the path + omitPath: function(obj, ks){ + if (typeof ks == "string") ks = ks.split("."); + + // If we have reached an undefined property + // then stop executing and return undefined + if (obj === undefined) return void 0; + + // If the path array has no more elements, we've reached + // the intended property and return its value + if (ks.length === 0) return obj; + + // If we still have elements in the path array and the current + // value is null, stop executing and return undefined + if (obj === null) return void 0; + + var copy = {}; + + var deepFunc = function (obj, path){ + if (!path) + path = []; + _.each(obj, function(value, key) { + if (_.isObject(value)){ + if (_.difference(ks, _.union(path, key)).length !== 0){ + if (_.isArray(value)){ + _.getPath(copy, path)[key] = []; + }else{ + _.getPath(copy, path)[key] = {}; + } + path.push(key); + deepFunc(value, path); + path.pop(key); + } + }else{ + if (_.difference(ks, _.union(path, key)).length !== 0) + _.getPath(copy, path)[key] = value; + } + }); + }; + deepFunc(obj); + + return copy; } });