mirror of
https://github.com/samsonjs/batteries.git
synced 2026-03-25 09:15:46 +00:00
126 lines
3.1 KiB
JavaScript
126 lines
3.1 KiB
JavaScript
exports.extendNative = function() {
|
|
Object.keys(ArrayExt).forEach(function(k) {
|
|
if (Array.prototype[k]) return; // don't overwrite existing members
|
|
Array.prototype[k] = function() {
|
|
var fn = ArrayExt[k]
|
|
, args = [].slice.call(arguments)
|
|
;
|
|
args.shift(this);
|
|
fn.apply(ArrayExt, args);
|
|
};
|
|
});
|
|
};
|
|
|
|
var ArrayToString = [].toString();
|
|
|
|
var ArrayExt = exports.ArrayExt = {
|
|
|
|
// abbrev
|
|
|
|
// [1,2,3,4,5].at(-1) => 5
|
|
at: function(a, i) {
|
|
if (i >= 0) return a[i];
|
|
return a[a.length + i];
|
|
}
|
|
|
|
// TODO make this work for non-array objects
|
|
, compact: function(a) {
|
|
var b = []
|
|
, i = a.length
|
|
;
|
|
while (i--) {
|
|
if (a[i] !== null && a[i] !== undefined) b[i] = a[i];
|
|
}
|
|
return b;
|
|
}
|
|
|
|
, first: function(a) { return a[0]; }
|
|
|
|
// Based on underscore.js's flatten
|
|
, flatten: function(a) {
|
|
return a.reduce(function(initial, elem) {
|
|
if (elem && elem.flatten) initial = initial.concat(elem.flatten());
|
|
else initial.push(elem);
|
|
return initial;
|
|
});
|
|
}
|
|
|
|
, grep: function(a, regex) {
|
|
return a.filter(function(v) { return regex.match(v); });
|
|
}
|
|
|
|
, last: function(a) { return a[a.length-1]; }
|
|
|
|
, max: function(a) {
|
|
return a.reduce(function(max, v) { return v > max ? v : max });
|
|
}
|
|
|
|
, min: function(a) {
|
|
return a.reduce(function(min, v) { return v < min ? v : min });
|
|
}
|
|
|
|
// pack
|
|
// partition
|
|
|
|
, pluck: function(a /* , key paths, ... */) {
|
|
var args = [].slice.call(arguments, 1);
|
|
args.unshift(a);
|
|
return pluck.apply(null, args);
|
|
}
|
|
|
|
, sortBy: function(arr, keyPath) {
|
|
return arr.slice().sort(function(a, b) {
|
|
var propA = drillInto(a)
|
|
, propB = drillInto(b);
|
|
if (propA < propB) return -1
|
|
if (propA > propB) return 1
|
|
return 0
|
|
});
|
|
}
|
|
|
|
, toString: function(a) {
|
|
return '[' + ArrayToString.call(a) + ']';
|
|
}
|
|
|
|
, unique: function(a) {
|
|
var b = []
|
|
, i = 0
|
|
, n = a.length
|
|
;
|
|
for (; i < n; ++i) {
|
|
if (b.indexOf(a[i]) === -1) b.push(a[i]);
|
|
}
|
|
return b;
|
|
}
|
|
};
|
|
|
|
|
|
// pluck
|
|
|
|
function getProp(thing, key) {
|
|
if (thing === null || thing === undefined) return thing
|
|
var prop = thing[key]
|
|
return typeof prop === 'function' ? prop.call(thing) : prop
|
|
}
|
|
|
|
function drillInto(thing, keyPath) {
|
|
return keyPath.split('.').reduce(function(memo, key) {
|
|
return getProp(memo, key)
|
|
}, thing)
|
|
}
|
|
|
|
function mapInto(thing /* , key paths, ... */) {
|
|
var keyPaths = [].slice.call(arguments, 1)
|
|
return keyPaths.map(function(keyPath) {
|
|
return drillInto(thing, keyPath)
|
|
})
|
|
}
|
|
|
|
function pluck(things /* , key paths, ... */) {
|
|
var keyPaths = [].slice.call(arguments, 1)
|
|
return things.map(function(thing) {
|
|
var results = mapInto.apply(null, [thing].concat(keyPaths))
|
|
if (results.length > 1) return results
|
|
return results[0]
|
|
})
|
|
}
|