Skip to content

Instantly share code, notes, and snippets.

@megawac
Forked from rjz/underscore.assign.js
Last active December 20, 2015 16:38
Show Gist options
  • Save megawac/6162481 to your computer and use it in GitHub Desktop.
Save megawac/6162481 to your computer and use it in GitHub Desktop.
/**
* Assign a value to the delimited key in the given object. The inverse of `_.lookup`
*
* @example
*
* var myObj = {};
*
* _.assign(myObj, 'foo.bar', 'baz'); // myObj = { foo: { bar: 'baz' }}
*
* @param {Object} obj the object to assign to
* @param {String} key the key to assign to
* @param {???} value the value
*/
_.mixin({
assign: function (obj, key, value) {
var keys = key.split('.'),
cur, ptr = obj;
while ((cur = keys.shift()) && keys.length) {
if (!_.isObject(ptr[cur])) {
ptr[cur] = {};
}
ptr = ptr[cur];
}
ptr[cur] = value;
return obj;
}
});
/**
* Filter a collection based on the value of a specified key
* Requires _.lookup
*
* @example
*
* var collection = [
* { type: 'fruit', name: 'Apple' }
* { type: 'vegetable', name: 'Sprouts' }
* { type: 'fruit', name: 'Orange' }
* ];
*
* _.filterBy(collection, 'type', 'fruit');
*
* @param {Array} list the collection to filter
* @param {String} key the key to compare
* @param {???} value the required value
*/
_.mixin({
filterBy: function (list, key, value) {
return _.filter(list, function (obj) {
return _.lookup(obj, key) === value;
});
}
});
/**
* Defer a function while an action is taking place
*
* @see http://blog.rjzaworski.com/2012/02/idling-with-underscore-js/
*
* @example
*
* // `foobar` will not run until 2 seconds after the last time
* // it was called:
* var foobar = _.idle(function() {
* console.log('tic-toc');
* }, 2000);
*
* foobar();
* @param {Function} code to run eventually
* @param {Number} delay time to delay after last function call
*/
_.mixin({
idle: function(code, delay, context) {
var handle;
if (typeof(context) == 'undefined') {
context = this;
}
return function() {
if (handle) {
window.clearTimeout(handle);
}
handle = window.setTimeout(_.bind(code, context), delay);
}
}
});
/**
* Return the value corresponding to the key in the given object
*
* @example
*
* var myObj = {
* foo: { bar: 'hello, world!' }
* };
*
* _.lookup(myObj, 'foo.bar'); // "hello, world!"
*
* @param {Object} obj the object containing the key
* @param {String} key the key to look up
*/
_.mixin({
lookup: function (obj, key) {
var type = typeof key, i = 0, length;
if (type == "string" || type == "number") {
key = ("" + key).replace(/\[(.*?)\]/g, function (m, key) { //handle case where [1] or ['xa'] may occur
return "." + key.replace(/^["']|["']$/g, ""); //strip quotes at the start or end of the key
}).split(".");
}
for (length = key.length; i < length; i++) {
if (_.has(obj, key[i])) obj = obj[key[i]];
else return void 0;
}
return obj;
}
});
Copy link

ghost commented Sep 10, 2014

in underscore.lookup.js
there should be

for(; i < key.length; i++) { //...

and remove the l variable in declaration line, because we don't want to get the length of the string

@megawac
Copy link
Author

megawac commented Sep 10, 2014

Thanks for the catch @wesleycoder

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment