Skip to content

Instantly share code, notes, and snippets.

@ssube
Created December 16, 2014 18:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ssube/b4e1e827e14105313312 to your computer and use it in GitHub Desktop.
Save ssube/b4e1e827e14105313312 to your computer and use it in GitHub Desktop.
/**
* Uses map syntax to retrieve the given object, or return null if any
* portion of the chain is null or undefined. The chain should be given with one
* field or method per argument. Methods will be called with the previous step as
* `this` and no arguments; this can be used for many string and array methods, as
* well as getters from various libraries.
*
* For example, given the object `foo = {bar: function (x) { return x+3; }};`, then
* `objectDig(foo, "bar.toExponential", [[2], [1]])` would return "5.0e+0".
*
* @param {Object} b The base object to work from.
* @param {String} h The chain of fields/methods to access, seperated by dots
* (eg, "foo.bar"). Any links in this chain may be prefixed with '!' to be not-ed
* while resolving.
* @param {Array} a An array containing arguments to any methods in the chain.
* Each method, when found, will be called with the then-head of this array, and the
* array moved to the next element. Null may be given to call a method without
* arguments, otherwise each function found in the chain will be passed one element
* from this array. This must be an array of arrays (standard `apply` semantics).
* @param {Object} df The default value. If any link in the chain is missing or
* no chain is given and `b` is undefined, this will be returned.
*
* @returns The last link in the given chain, or `df` if the chain could not be completed.
*/
function objectDig(b, h, a, df) {
if (typeof b == "undefined" || !h) {
return b;
}
var l = h.split('.'), c = _.clone(a || []), ll = l.length;
df = df || null;
for (var i = 0; i < ll; ++i) {
if (_.isUndefined(b) || _.isNull(b)) {
return df;
}
var li = l[i], f = false;
if (li[0] == '!') {
f = true;
li = li.substr(1);
}
var d = b[li];
if (_.isFunction(d)) {
d = d.apply(b, _.first(c) || []);
c = c ? _.rest(c) : null;
}
b = f ? !d : d;
}
if (_.isUndefined(b)) {
b = df;
}
return b;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment