Comparing version 1.3.2 to 1.4.0
61
index.js
@@ -1,3 +0,3 @@ | ||
function isObject (o) { | ||
return o && 'object' === typeof o && !Array.isArray(o) | ||
function isObject (o, allowArray) { | ||
return o && 'object' === typeof o && (allowArray || !Array.isArray(o)) | ||
} | ||
@@ -17,2 +17,6 @@ | ||
function isNonNegativeInteger (i) { | ||
return Number.isInteger(i) && i >= 0 | ||
} | ||
function set (obj, path, value) { | ||
@@ -25,3 +29,3 @@ if(!obj) throw new Error('libnested.set: first arg must be an object') | ||
else if(null == obj[path[i]]) | ||
obj = (obj[path[i]] = {}) | ||
obj = (obj[path[i]] = isNonNegativeInteger(path[i]) ? [] : {}) | ||
else | ||
@@ -32,27 +36,46 @@ obj = obj[path[i]] | ||
function each (obj, iter, path) { | ||
function each (obj, iter, includeArrays, path) { | ||
path = path || [] | ||
for(var k in obj) { | ||
if(isObject(obj[k])) { | ||
if(false === each(obj[k], iter, path.concat(k))) return false | ||
} else { | ||
if(false === iter(obj[k], path.concat(k))) return false | ||
//handle array separately, so that arrays can have integer keys | ||
if(Array.isArray(obj)) { | ||
if(!includeArrays) return false | ||
for(var k = 0; k < obj.length; k++) { | ||
//loop content is duplicated, so that return works | ||
var v = obj[k] | ||
if(isObject(v, includeArrays)) { | ||
if(false === each(v, iter, includeArrays, path.concat(k))) | ||
return false | ||
} else { | ||
if(false === iter(v, path.concat(k))) return false | ||
} | ||
} | ||
} | ||
else { | ||
for(var k in obj) { | ||
//loop content is duplicated, so that return works | ||
var v = obj[k] | ||
if(isObject(v, includeArrays)) { | ||
if(false === each(v, iter, includeArrays, path.concat(k))) | ||
return false | ||
} else { | ||
if(false === iter(v, path.concat(k))) return false | ||
} | ||
} | ||
} | ||
return true | ||
} | ||
function map (obj, iter, out) { | ||
function map (obj, iter, out, includeArrays) { | ||
var out = out || Array.isArray(obj) ? [] : {} | ||
each(obj, function (val, path) { | ||
set(out, path, iter(val, path)) | ||
}) | ||
}, includeArrays) | ||
return out | ||
} | ||
function paths (obj) { | ||
function paths (obj, incluedArrays) { | ||
var out = [] | ||
each(obj, function (_, path) { | ||
out.push(path) | ||
}) | ||
}, incluedArrays) | ||
return out | ||
@@ -63,4 +86,10 @@ } | ||
//note, cyclic objects are not supported. | ||
//will cause an stack overflow. | ||
function clone (obj) { | ||
return map(obj, id) | ||
if(!isObject(obj, true)) return obj | ||
var _obj | ||
_obj = Array.isArray(obj) ? [] : {} | ||
for(var k in obj) _obj[k] = clone(obj[k]) | ||
return _obj | ||
} | ||
@@ -74,1 +103,5 @@ | ||
exports.clone = clone | ||
exports.copy = clone | ||
{ | ||
"name": "libnested", | ||
"description": "", | ||
"version": "1.3.2", | ||
"version": "1.4.0", | ||
"homepage": "https://github.com/dominictarr/libnested", | ||
@@ -6,0 +6,0 @@ "repository": { |
@@ -7,3 +7,3 @@ # libnested | ||
### each (object, iter(value, path)) => boolean | ||
### each (object, iter(value, path), includeArrays?) => boolean | ||
@@ -16,6 +16,13 @@ iterate over an object (depth first) and call `iter` with each value. | ||
### map (object, iter(value, path) => nextValue, output) => output | ||
if `includeArrays` is true (defaults to false) then arrays | ||
encounted will be treated like objects. If `includeArrays` | ||
is not true, arrays will be treated like `values`. | ||
### map (object, iter(value, path) => nextValue, output, includeArrays?) => output | ||
map over a nested object (depth first). A new object is returned (unless `output` is given), containing values returned by `iter`. | ||
if `includeArrays` is true, the contents of arrays will be mapped, | ||
otherwise only the arrays themselves will be. | ||
### paths (object) => [path...] | ||
@@ -39,2 +46,4 @@ | ||
`object` will be mutated. | ||
### clone (object) | ||
@@ -44,4 +53,7 @@ | ||
cyclic objects are not supported - will produce a `RangeError` (stackoverflow) | ||
## License | ||
MIT | ||
38
test.js
@@ -103,4 +103,42 @@ | ||
tape('include arrays', function (t) { | ||
var deep = {foo: {bar: true}, baz: 2, blurg: {fop: {hif: [1,2,3]}}} | ||
t.deepEqual( | ||
R.paths(deep, true), | ||
[ | ||
['foo', 'bar'], | ||
['baz'], | ||
['blurg', 'fop', 'hif', 0], | ||
['blurg', 'fop', 'hif', 1], | ||
['blurg', 'fop', 'hif', 2] | ||
] | ||
) | ||
var o = {} | ||
R.set(o, ['hello', 0, 'okay'], true), | ||
t.deepEqual( | ||
o, | ||
{hello: [{okay: true}]} | ||
) | ||
t.end() | ||
}) | ||
tape('clone does not leave an array reference', function (t) { | ||
var a = {foo: [1]} | ||
t.deepEqual(R.clone(a), a) | ||
t.notEqual(a.foo, R.clone(a).foo) | ||
var b = {foo: [{}], bar: {}} | ||
t.deepEqual(R.clone(b), b) | ||
t.notEqual(b.foo, R.clone(b).foo) | ||
t.notEqual(b.foo[0], R.clone(b).foo[0]) | ||
t.notEqual(b.bar, R.clone(b).bar) | ||
t.end() | ||
}) | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
7993
199
56