Skip to content

Instantly share code, notes, and snippets.

@sarink
Last active August 29, 2015 14:04
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 sarink/bf4fa3a0760a2cb59e03 to your computer and use it in GitHub Desktop.
Save sarink/bf4fa3a0760a2cb59e03 to your computer and use it in GitHub Desktop.
(function(root, factory) {
if (typeof define === "function" && define.amd) {
define(["underscore"], function(_) {
return factory(_);
});
}
else if (typeof exports !== "undefined") {
var _ = require("underscore");
module.exports = factory(_);
}
else {
factory(root._);
}
}(this, function(_) {
"use strict";
_.mixin({
// Pass an array of numbers, return the sum of all its values
sum: function(arr) {
return (!_.isArray(arr) || arr.length === 0) ? 0 : _.reduce(_.flatten(arr), function(sum, n) {return sum + n;}, 0);
},
// Removes the first instance of `obj` from `arr`, returns the removed object
remove: function(arr, obj, options) {
options = _.defaults(options || {}, {deepEqual: false});
var result;
if (_.isArray(arr)) {
for (var i = 0, l = arr.length; i < l; i++) {
var o = arr[i];
var match = (options.deepEqual) ? _.isEqual(o, obj) : o === obj;
if (match) {
result = arr[i];
arr.splice(i, 1);
break;
}
}
}
return result;
},
// Just like `_.result`, except if `prop` is a function, you can pass it a `context`
bindAndResult: function(obj, prop, context, args) {
return (_.isFunction(obj[prop])) ? obj[prop].apply(context, (args || [])) : obj[prop];
},
// Copies value at `obj[currentKey]` to `obj[newKey]`, then deletes `obj[currentKey]`
changeKey: function(obj, currentKey, newKey) {
if (obj[currentKey] !== void 0 && currentKey !== newKey) {
obj[newKey] = obj[currentKey];
delete obj[currentKey];
}
return obj;
},
// Plucks a Backbone property from a javascript array of Backbone models.
bbPluck: function(models, propName) {
return _.map(models, function(m) { return m.get(propName); });
},
// Recursively transforms all keys on an object, according to `transformFunction`
deepTransformKeys: function(obj, transformFunction) {
if (!obj || !_.isObject(obj) || obj.__visited__) return obj;
if (_.isDate(obj) || _.isRegExp(obj)) return obj;
// Put down a marker to prevent cycles
obj.__visited__ = true;
// Handle arrays of objects
if (_.isArray(obj)) {
_.each(obj, function(o) { _.deepTransformKeys(o, transformFunction); });
delete obj.__visited__;
return obj;
}
// Transform each key, then run this recursively on the values of the object
_.each(obj, function(value, key) {
var newKey = transformFunction(key);
if (key !== "__visited__" && newKey !== key) {
obj[newKey] = value;
delete obj[key];
}
_.deepTransformKeys(obj[newKey], transformFunction);
});
delete obj.__visited__;
return obj;
},
// Recursively camelCases all key names on an object
deepCamelizeKeys: function(obj) {
return _.deepTransformKeys(obj, _.camelize);
},
// Recursively snake_cases all key names on an object
deepSnakeizeKeys: function(obj) {
return _.deepTransformKeys(obj, _.snakeize);
},
// Convert a string to camelCase
camelize: function(str) {
return (_.isString(str)) ? str.replace(/[_.-](\w|$)/g, function($1, $2) { return $2.toUpperCase(); }) : str;
},
// Convert a string to snake_case
snakeize: function(str) {
return (_.isString(str)) ? str.replace(/([A-Z])/g, function($1) { return "_"+$1.toLowerCase(); }) : str;
}
});
return _;
}));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment