Socket
Socket
Sign inDemoInstall

underscore.deep

Package Overview
Dependencies
0
Maintainers
4
Versions
13
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.1.0 to 0.2.0

test/helpers.coffee

2

package.json
{
"name": "underscore.deep",
"version": "0.1.0",
"version": "0.2.0",
"description": "Underscore mixins for deeply nested objects",

@@ -5,0 +5,0 @@ "main": "underscore.deep.js",

@@ -7,3 +7,3 @@ # underscore.deep

This README is written in [Literate CoffeeScript](http://coffeescript.org/#literate) as a [Mocha](http://visionmedia.github.io/mocha/) test suite, so you can execute all of the examples - just run:
```

@@ -30,3 +30,5 @@ make README.coffee.md

describe 'underscore.deep', ->
{assert, _} = require './test/readmeHelpers'
assert = require 'assert'
_ = require 'underscore'
_.mixin require './underscore.deep'

@@ -51,7 +53,7 @@ ### _.deepToFlat(obj)

age: 33
),
),
'user1.name.first': 'Deep'
'user1.name.last': 'Blue'
'user1.age': '33'
### _.deepFromFlat(obj)

@@ -128,8 +130,161 @@

### _.deepHas
### _.deepHas(obj, key)
TODO
Takes an object `obj` and a string `key` (which should be a dot-notation key) and returns true if `obj` has a nested field named `key`.
### _.deepKeys
describe '_.deepHas', ->
TODO
obj = we: have: to: go: 'deeper'
it 'returns true if a regular key exists', ->
assert.equal _.deepHas(obj, 'we'), true
it 'returns true if the deep key exists', ->
assert.equal _.deepHas(obj, 'we.have'), true
assert.equal _.deepHas(obj, 'we.have.to'), true
assert.equal _.deepHas(obj, 'we.have.to.go'), true
it 'returns false if the deep key does not exist', ->
assert.equal _.deepHas(obj, 'we.have.to.goop'), false
it 'is not equivalent to the composition of _.has and _.deepToFlat', ->
assert.equal _.deepHas(obj, 'we.have.to.go'), _.has(_.deepToFlat(obj), 'we.have.to.go')
assert.equal _.deepHas(obj, 'we.have.to.goop'), _.has(_.deepToFlat(obj), 'we.have.to.goop')
assert.notEqual _.deepHas(obj, 'we'), _.has(_.deepToFlat(obj), 'we')
### _.deepKeys(obj)
Takes an object and returns all of its nested keys in dot-notation.
If you think of a deeply-nested object as a tree, then it will return the paths to all of the tree's leaves. That means it won't return intermediate keys. As a consequence, `_.deepHas(obj, key)` is not equivalent to `_.contains _.deepKeys(obj), key`.
describe '_.deepKeys', ->
obj =
node1:
leaf1: 1
node2:
node3:
leaf2: 2
leaf3: 3
it 'returns dot-notation keys for only the leaf fields of an object', ->
assert.deepEqual _.deepKeys(obj), [
'node1.leaf1'
'node2.node3.leaf2'
'node2.node3.leaf3'
]
it 'is equivalent to the composition of _.keys and _.deepToFlat', ->
assert.deepEqual _.deepKeys(obj), _.keys(_.deepToFlat obj)
it 'does not make _.deepHas equivalent to the composition of _.contains and _.deepKeys', ->
assert.notDeepEqual _.contains(_.deepKeys(obj), 'node1'), _.has(obj, 'node1')
### _.deepExtend(destination, source, mutate = false)
Takes an object `destination` and an object `source` and creates a new object with all the deep fields of `destination` and all the deep fields of `source`. Any deep fields with the same deep key in `destination` and `source` will have the value from `source` (so `source` fields overwrite `destination` fields).
Unlike `_.extend`, `_.deepExtend` is pure, so the original objects `destination` and `source` will not be modified. If you really want to mutate `destination` by adding the deep fields of `source`, pass `true` as the third parameter `mutate`.
describe '_.deepExtend', ->
destination =
name: 'heaven'
angels:
michael: true
it 'combines all the deep fields of destination and source', ->
assert.deepEqual _.deepExtend(destination, { angels: gabriel: false }),
name: 'heaven'
angels:
michael: true
gabriel: false
it 'overwrites fields of destination with fields from source', ->
assert.deepEqual _.deepExtend(destination, { angels: michael: false }),
name: 'heaven'
angels:
michael: false
it 'does not mutate the input objects', ->
assert.notStrictEqual destination, _.deepExtend(destination, { name: 'hell' })
it 'is equivalent to a weird composition of _.deepFromFlat, _.extend, and _.deepToFlat', ->
assert.deepEqual _.deepExtend(destination, { angels: gabriel: false }),
_.deepFromFlat _.extend _.deepToFlat(destination), _.deepToFlat({ angels: gabriel: false })
### _.deepMapValues(obj, func)
Like [_.mapValues](#_mapvaluesobj-func), but for deep objects. Constructs a new object by applying function `func` to the value for every deep field in object `obj`.
describe '_.deepMapValues', ->
obj =
values:
empathy: true
responsibility: false
it 'creates an object by applying func to each deep value in obj', ->
assert.deepEqual _.deepMapValues(obj, (v) -> not v),
values:
empathy: false
responsibility: true
it 'is equivalent to the composition of _.deepFromFlat, _.mapValues, and _.deepToFlat', ->
assert.deepEqual _.deepMapValues(obj, (v) -> String v),
_.deepFromFlat _.mapValues _.deepToFlat(obj), (v) -> String v
## Non-deep Helpers
Someday these will probably be moved into their own library, but for now they live here.
### _.isPlainObject(val)
Takes a value `val` and returns `true` if it's a vanilla JS object (i.e. not an instance of any built-in or custom class). Otherwise returns false.
describe '_.isPlainObject', ->
it 'returns true for vanilla objects', ->
assert.equal _.isPlainObject({}), true
assert.equal _.isPlainObject({ vanilla: 'is so plain' }), true
it 'returns false for other values', ->
assert.equal _.isPlainObject(1), false
assert.equal _.isPlainObject('chocolate'), false
assert.equal _.isPlainObject(new Date()), false
### _.mapValues(obj, func)
Takes an object `obj` and a function `func` and constructs a new object by applying `func` to every value in `obj`. `func` receives two arguments, the value and the key for that value.
Some have [described](https://github.com/jashkenas/underscore/issues/220#issuecomment-12112759) this function as "the fundamental map over dictionaries." Others have [said](https://github.com/jashkenas/underscore/issues/220#issuecomment-1470150) its not "mainstream enough to deserve to make it into Underscore proper." We take no stance in the debate, but we have to admit we use it on the daily.
describe '_.mapValues', ->
obj =
respect: 1
fairness: 2
it 'creates an object by applying func to each value in obj', ->
assert.deepEqual _.mapValues(obj, (v) -> v * 10),
respect: 10
fairness: 20
### _.mapKeys(obj, func)
Exactly like [_.mapValues](#_mapvaluesobj-func) but for keys.
Note that the function takes a function takes a key and optionally a value, not the usual mapping function pattern of taking a value and optionally a key
describe '_.mapKeys', ->
obj =
animate: 1
charge: 2
it 'creates an object by applying func to each key in obj', ->
assert.deepEqual _.mapKeys(obj, (key) -> 're' + key),
reanimate: 1
recharge: 2
it 'creates an object by applying func to each key, val in obj', ->
assert.deepEqual _.mapKeys(obj, (key, val) -> 're' + key + val),
reanimate1: 1
recharge2: 2
// Generated by CoffeeScript 1.6.3
var deepClone, deepDelete, deepExtend, deepKeys, deepMapValues, isPlainObject, mapValues, _;
var deepClone, deepDelete, deepExtend, deepKeys, deepMapValues, isPlainObject, mapKeys, mapValues, _;

@@ -7,17 +7,15 @@ _ = require('underscore');

module.exports = {
deepKeys: deepKeys = function(obj, prefix) {
var key, keys, val;
if (prefix == null) {
prefix = '';
deepKeys: deepKeys = function(obj) {
if (!isPlainObject(obj)) {
throw new Error("deepKeys must be called on an object, not '" + obj + "'");
}
keys = [];
for (key in obj) {
val = obj[key];
if (_.isObject(val) && !_.isArray(val) && !_.isEmpty(val)) {
keys = _.union(keys, deepKeys(val, "" + prefix + key + "."));
return _.flatten(_.map(obj, function(v, k) {
if (isPlainObject(v) && !_.isEmpty(v)) {
return _.map(deepKeys(v), function(subkey) {
return "" + k + "." + subkey;
});
} else {
keys.push("" + prefix + key);
return [k];
}
}
return keys;
}));
},

@@ -125,13 +123,27 @@ deepClone: deepClone = function(object) {

mapValues: mapValues = function(obj, f_val) {
if (!_.isPlainObject(obj)) {
throw new Error("mapValues must be called on an object, not '" + obj + "'");
}
return _.object(_.keys(obj), _.map(obj, f_val));
},
deepMapValues: deepMapValues = function(obj, f) {
if (isPlainObject(obj)) {
return mapValues(obj, function(v) {
if (!_.isPlainObject(obj)) {
throw new Error("deepMapValues must be called on an object, not '" + obj + "'");
}
return mapValues(obj, function(v) {
if (_.isPlainObject(v)) {
return deepMapValues(v, f);
});
} else {
return f(obj);
} else {
return f(v);
}
});
},
mapKeys: mapKeys = function(obj, f_val) {
if (!_.isPlainObject(obj)) {
throw new Error("mapKeys must be called on an object, not '" + obj + "'");
}
return _.object(_.map(obj, function(v, k) {
return f_val(k, v);
}), _.values(obj));
}
};

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc