underscore.deep
Version:
Underscore mixins for deeply nested objects
127 lines (124 loc) • 3.35 kB
JavaScript
// Generated by CoffeeScript 1.6.3
var deepClone, deepDelete, deepExtend, deepKeys, isPlainObject, mapValues, _;
_ = require('underscore');
module.exports = {
deepKeys: deepKeys = function(obj, prefix) {
var key, keys, val;
if (prefix == null) {
prefix = '';
}
keys = [];
for (key in obj) {
val = obj[key];
if (_.isObject(val) && !_.isArray(val)) {
keys = _.union(keys, deepKeys(val, "" + prefix + key + "."));
} else {
keys.push("" + prefix + key);
}
}
return keys;
},
deepClone: deepClone = function(object) {
var type, _i, _len, _ref;
if (object == null) {
return object;
}
_ref = [Date, Number, String, Boolean];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
type = _ref[_i];
if (object instanceof type) {
return new type(object);
}
}
if (_(object).isArray()) {
return _(object).map(deepClone);
}
if (!_(object).isObject()) {
return object;
}
if (object.nodeType && _(object.cloneNode).isFunction()) {
return object.cloneNode(true);
}
if (object.constructor !== {}.constructor) {
return object;
}
return mapValues(object, deepClone);
},
deepHas: function(obj, keys) {
var helper;
helper = function(obj, keys) {
if ((keys.length === 0) || (!_.isObject(obj))) {
return false;
} else if (keys.length === 1) {
return _.first(keys) in obj;
} else {
return helper(obj[_.first(keys)], _.rest(keys));
}
};
return helper(obj, _.isArray(keys) ? keys : keys.split('.'));
},
deepDelete: deepDelete = function(obj, key) {
if ((key == null) || (obj == null)) {
return;
}
if (!_(key).isArray()) {
key = key.split('.');
}
if (key.length === 1) {
delete obj[key];
return;
}
return deepDelete(obj[key[0]], key.slice(1, key.length));
},
deepExtend: deepExtend = function(obj, ext, mutate) {
var _this = this;
return _.reduce(ext, function(acc, val, key) {
acc[key] = (key in obj) && isPlainObject(obj[key]) && isPlainObject(val) ? deepExtend(obj[key], val) : val;
return acc;
}, mutate ? obj : _.clone(obj));
},
isPlainObject: isPlainObject = function(value) {
return value.constructor === {}.constructor;
},
flatten: function(obj) {
var recurse, res;
res = {};
recurse = function(obj, current) {
var key, newKey, value, _results;
_results = [];
for (key in obj) {
value = obj[key];
newKey = (current ? current + "." + key : key);
if (value && isPlainObject(value)) {
_results.push(recurse(value, newKey));
} else {
_results.push(res[newKey] = value);
}
}
return _results;
};
recurse(obj);
return res;
},
deepen: function(o) {
var k, key, oo, part, parts, t;
oo = {};
t = void 0;
parts = void 0;
part = void 0;
for (k in o) {
t = oo;
parts = k.split(".");
key = parts.pop();
while (parts.length) {
part = parts.shift();
t = t[part] = t[part] || {};
}
t[key] = o[k];
}
return oo;
},
mapValues: mapValues = function(obj, f_val) {
return _.object(_.keys(obj), _.map(obj, f_val));
}
};