dot-component
Version:
MongoDB-style "dot notation" querying for JavaScript.
83 lines (71 loc) • 1.78 kB
JavaScript
/**
* Module dependencies.
*/
var type = require('type-component');
/**
* Gets a certain `path` from the `obj`.
*
* @param {Object} target
* @param {String} key
* @return {Object} found object, or `undefined
* @api public
*/
exports.get = function(obj, path){
if (~path.indexOf('.')) {
var par = parent(obj, path);
var mainKey = path.split('.').pop();
var t = type(par);
if ('object' == t || 'array' == t) return par[mainKey];
} else {
return obj[path];
}
};
/**
* Sets the given `path` to `val` in `obj`.
*
* @param {Object} target
* @Param {String} key
* @param {Object} value
* @api public
*/
exports.set = function(obj, path, val){
if (~path.indexOf('.')) {
var par = parent(obj, path, true);
var mainKey = path.split('.').pop();
if (par && 'object' == type(par)) par[mainKey] = val;
} else {
obj[path] = val;
}
};
/**
* Gets the parent object for a given key (dot notation aware).
*
* - If a parent object doesn't exist, it's initialized.
* - Array index lookup is supported
*
* @param {Object} target object
* @param {String} key
* @param {Boolean} true if it should initialize the path
* @api public
*/
exports.parent = parent;
function parent(obj, key, init){
if (~key.indexOf('.')) {
var pieces = key.split('.');
var ret = obj;
for (var i = 0; i < pieces.length - 1; i++) {
// if the key is a number string and parent is an array
if (Number(pieces[i]) == pieces[i] && 'array' == type(ret)) {
ret = ret[pieces[i]];
} else if ('object' == type(ret)) {
if (init && !ret.hasOwnProperty(pieces[i])) {
ret[pieces[i]] = {};
}
if (ret) ret = ret[pieces[i]];
}
}
return ret;
} else {
return obj;
}
}