mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-02-02 08:07:50 +00:00
Add _.transform.
Former-commit-id: 6c040fedd130e8436ff99b1d70892ac8cebbb996
This commit is contained in:
65
build.js
65
build.js
@@ -88,7 +88,7 @@
|
||||
'contains': ['indexOf', 'isString'],
|
||||
'countBy': ['createCallback', 'forEach'],
|
||||
'createCallback': ['identity', 'isEqual', 'keys'],
|
||||
'debounce': [],
|
||||
'debounce': ['isObject'],
|
||||
'defaults': ['isArray', 'keys'],
|
||||
'defer': ['bind'],
|
||||
'delay': [],
|
||||
@@ -163,9 +163,10 @@
|
||||
'sortedIndex': ['createCallback', 'identity'],
|
||||
'tap': ['value'],
|
||||
'template': ['defaults', 'escape', 'keys', 'values'],
|
||||
'throttle': [],
|
||||
'throttle': ['isObject'],
|
||||
'times': ['createCallback'],
|
||||
'toArray': ['isString', 'values'],
|
||||
'transform': ['createCallback', 'forOwn', 'isArray', 'isObject'],
|
||||
'unescape': [],
|
||||
'union': ['isArray', 'uniq'],
|
||||
'uniq': ['createCallback', 'indexOf'],
|
||||
@@ -276,6 +277,7 @@
|
||||
'parseInt',
|
||||
'partialRight',
|
||||
'runInContext',
|
||||
'transform',
|
||||
'unzip'
|
||||
];
|
||||
|
||||
@@ -800,7 +802,7 @@
|
||||
* @returns {String} Returns the `isArguments` fallback.
|
||||
*/
|
||||
function getIsArgumentsFallback(source) {
|
||||
return (source.match(/(?:\s*\/\/.*)*\n( *)if *\((?:!support\.argsClass|!isArguments)[\s\S]+?};\n\1}/) || [''])[0];
|
||||
return (source.match(/(?:\s*\/\/.*)*\n( *)if *\((?:!support\.argsClass|!isArguments)[\s\S]+?\n *};\n\1}/) || [''])[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -824,7 +826,18 @@
|
||||
* @returns {String} Returns the `isFunction` fallback.
|
||||
*/
|
||||
function getIsFunctionFallback(source) {
|
||||
return (source.match(/(?:\s*\/\/.*)*\n( *)if *\(isFunction\(\/x\/[\s\S]+?};\n\1}/) || [''])[0];
|
||||
return (source.match(/(?:\s*\/\/.*)*\n( *)if *\(isFunction\(\/x\/[\s\S]+?\n *};\n\1}/) || [''])[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `createObject` fallback from `source`.
|
||||
*
|
||||
* @private
|
||||
* @param {String} source The source to inspect.
|
||||
* @returns {String} Returns the `isArguments` fallback.
|
||||
*/
|
||||
function getCreateObjectFallback(source) {
|
||||
return (source.match(/(?:\s*\/\/.*)*\n( *)if *\((?:!nativeCreate)[\s\S]+?\n *};\n\1}/) || [''])[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1069,6 +1082,17 @@
|
||||
return source.replace(getIsFunctionFallback(source), '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the `createObject` fallback from `source`.
|
||||
*
|
||||
* @private
|
||||
* @param {String} source The source to process.
|
||||
* @returns {String} Returns the modified source.
|
||||
*/
|
||||
function removeCreateObjectFallback(source) {
|
||||
return source.replace(getCreateObjectFallback(source), '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the `Object.keys` object iteration optimization from `source`.
|
||||
*
|
||||
@@ -1939,11 +1963,11 @@
|
||||
source = removeSupportProp(source, 'fastBind');
|
||||
source = replaceSupportProp(source, 'argsClass', 'false');
|
||||
|
||||
_.each(['getPrototypeOf', 'nativeBind', 'nativeIsArray', 'nativeKeys'], function(varName) {
|
||||
_.each(['getPrototypeOf'], function(varName) {
|
||||
source = replaceVar(source, varName, 'false');
|
||||
});
|
||||
|
||||
_.each(['isIeOpera', 'isV8', 'nativeBind', 'nativeIsArray', 'nativeKeys', 'reNative'], function(varName) {
|
||||
_.each(['isIeOpera', 'isV8', 'nativeBind', 'nativeCreate', 'nativeIsArray', 'nativeKeys', 'reNative'], function(varName) {
|
||||
source = removeVar(source, varName);
|
||||
});
|
||||
|
||||
@@ -1957,6 +1981,23 @@
|
||||
return match.replace(/\bnativeIsArray\s*\|\|\s*/, '');
|
||||
});
|
||||
|
||||
// replace `createObject` and `isArguments` with their fallbacks
|
||||
_.each({
|
||||
'createObject': { 'get': getCreateObjectFallback, 'remove': removeCreateObjectFallback },
|
||||
'isArguments': { 'get': getIsArgumentsFallback, 'remove': removeIsArgumentsFallback }
|
||||
},
|
||||
function(util, methodName) {
|
||||
source = source.replace(matchFunction(source, methodName).replace(RegExp('[\\s\\S]+?function ' + methodName), ''), function() {
|
||||
var snippet = util.get(source),
|
||||
body = snippet.match(RegExp(methodName + ' *= *function([\\s\\S]+?\\n *});'))[1],
|
||||
indent = getIndent(snippet);
|
||||
|
||||
return body.replace(RegExp('^' + indent, 'gm'), indent.slice(0, -2)) + '\n';
|
||||
});
|
||||
|
||||
source = util.remove(source);
|
||||
});
|
||||
|
||||
// replace `_.keys` with `shimKeys`
|
||||
source = source.replace(
|
||||
matchFunction(source, 'keys').replace(/[\s\S]+?var keys *= */, ''),
|
||||
@@ -1964,17 +2005,6 @@
|
||||
);
|
||||
|
||||
source = removeFunction(source, 'shimKeys');
|
||||
|
||||
// replace `_.isArguments` with fallback
|
||||
source = source.replace(matchFunction(source, 'isArguments').replace(/[\s\S]+?function isArguments/, ''), function() {
|
||||
var fallback = getIsArgumentsFallback(source),
|
||||
body = fallback.match(/isArguments *= *function([\s\S]+? *});/)[1],
|
||||
indent = getIndent(fallback);
|
||||
|
||||
return body.replace(RegExp('^' + indent, 'gm'), indent.slice(0, -2)) + '\n';
|
||||
});
|
||||
|
||||
source = removeIsArgumentsFallback(source);
|
||||
}
|
||||
if (isModern) {
|
||||
source = removeSupportSpliceObjects(source);
|
||||
@@ -1987,6 +2017,7 @@
|
||||
else {
|
||||
source = removeIsArrayFallback(source);
|
||||
source = removeIsFunctionFallback(source);
|
||||
source = removeCreateObjectFallback(source);
|
||||
|
||||
// remove `shimIsPlainObject` from `_.isPlainObject`
|
||||
source = source.replace(matchFunction(source, 'isPlainObject'), function(match) {
|
||||
|
||||
@@ -222,6 +222,7 @@
|
||||
'times',
|
||||
'toArray',
|
||||
'trailing',
|
||||
'transform',
|
||||
'unescape',
|
||||
'unindexedChars',
|
||||
'union',
|
||||
|
||||
86
lodash.js
86
lodash.js
@@ -198,6 +198,7 @@
|
||||
|
||||
/* Native method shortcuts for methods with the same name as other `lodash` methods */
|
||||
var nativeBind = reNative.test(nativeBind = toString.bind) && nativeBind,
|
||||
nativeCreate = reNative.test(nativeCreate = Object.create) && nativeCreate,
|
||||
nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
|
||||
nativeIsFinite = context.isFinite,
|
||||
nativeIsNaN = context.isNaN,
|
||||
@@ -264,8 +265,8 @@
|
||||
* `invoke`, `keys`, `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`,
|
||||
* `once`, `pairs`, `partial`, `partialRight`, `pick`, `pluck`, `push`, `range`,
|
||||
* `reject`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`,
|
||||
* `tap`, `throttle`, `times`, `toArray`, `union`, `uniq`, `unshift`, `unzip`,
|
||||
* `values`, `where`, `without`, `wrap`, and `zip`
|
||||
* `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, `unshift`,
|
||||
* `unzip`, `values`, `where`, `without`, `wrap`, and `zip`
|
||||
*
|
||||
* The non-chainable wrapper functions are:
|
||||
* `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `has`,
|
||||
@@ -771,9 +772,7 @@
|
||||
}
|
||||
if (this instanceof bound) {
|
||||
// ensure `new bound` is an instance of `func`
|
||||
noop.prototype = func.prototype;
|
||||
thisBinding = new noop;
|
||||
noop.prototype = null;
|
||||
thisBinding = createObject(func.prototype);
|
||||
|
||||
// mimic the constructor's `return` behavior
|
||||
// http://es5.github.com/#x13.2.2
|
||||
@@ -839,6 +838,28 @@
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new object with the specified `prototype`.
|
||||
*
|
||||
* @private
|
||||
* @param {Object} prototype The prototype object.
|
||||
* @returns {Object} Returns the new object.
|
||||
*/
|
||||
function createObject(prototype) {
|
||||
return isObject(prototype) ? nativeCreate(prototype) : {};
|
||||
}
|
||||
// fallback for browsers without `Object.create`
|
||||
if (!nativeCreate) {
|
||||
var createObject = function(prototype) {
|
||||
if (isObject(prototype)) {
|
||||
noop.prototype = prototype;
|
||||
var result = new noop;
|
||||
noop.prototype = null;
|
||||
}
|
||||
return result || {};
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by `template` to escape characters for inclusion in compiled
|
||||
* string literals.
|
||||
@@ -2278,6 +2299,56 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transforms an `object` to an new `accumulator` object which is the result
|
||||
* of running each of its elements through the `callback`, with each `callback`
|
||||
* execution potentially mutating the `accumulator` object. The `callback`is
|
||||
* bound to `thisArg` and invoked with four arguments; (accumulator, value, key, object).
|
||||
* Callbacks may exit iteration early by explicitly returning `false`.
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @category Objects
|
||||
* @param {Array|Object} collection The collection to iterate over.
|
||||
* @param {Function} [callback=identity] The function called per iteration.
|
||||
* @param {Mixed} [accumulator] The custom accumulator value.
|
||||
* @param {Mixed} [thisArg] The `this` binding of `callback`.
|
||||
* @returns {Mixed} Returns the accumulated value.
|
||||
* @example
|
||||
*
|
||||
* var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
|
||||
* num *= num;
|
||||
* if (num % 2) {
|
||||
* return result.push(num) < 3;
|
||||
* }
|
||||
* });
|
||||
* // => [1, 9, 25]
|
||||
*
|
||||
* var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
|
||||
* result[key] = num * 3;
|
||||
* });
|
||||
* // => { 'a': 3, 'b': 6, 'c': 9 }
|
||||
*/
|
||||
function transform(object, callback, accumulator, thisArg) {
|
||||
var isArr = isArray(object);
|
||||
callback = lodash.createCallback(callback, thisArg, 4);
|
||||
|
||||
if (arguments.length < 3) {
|
||||
if (isArr) {
|
||||
accumulator = [];
|
||||
} else {
|
||||
var ctor = object && object.constructor,
|
||||
proto = ctor && ctor.prototype;
|
||||
|
||||
accumulator = createObject(proto);
|
||||
}
|
||||
}
|
||||
(isArr ? each : forOwn)(object, function(value, index, object) {
|
||||
return callback(accumulator, value, index, object);
|
||||
});
|
||||
return accumulator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array composed of the own enumerable property values of `object`.
|
||||
*
|
||||
@@ -4547,7 +4618,7 @@
|
||||
if (options === true) {
|
||||
var leading = true;
|
||||
trailing = false;
|
||||
} else if (options && objectTypes[typeof options]) {
|
||||
} else if (isObject(options)) {
|
||||
leading = options.leading;
|
||||
trailing = 'trailing' in options ? options.trailing : trailing;
|
||||
}
|
||||
@@ -4776,7 +4847,7 @@
|
||||
}
|
||||
if (options === false) {
|
||||
leading = false;
|
||||
} else if (options && objectTypes[typeof options]) {
|
||||
} else if (isObject(options)) {
|
||||
leading = 'leading' in options ? options.leading : leading;
|
||||
trailing = 'trailing' in options ? options.trailing : trailing;
|
||||
}
|
||||
@@ -5384,6 +5455,7 @@
|
||||
lodash.throttle = throttle;
|
||||
lodash.times = times;
|
||||
lodash.toArray = toArray;
|
||||
lodash.transform = transform;
|
||||
lodash.union = union;
|
||||
lodash.uniq = uniq;
|
||||
lodash.unzip = unzip;
|
||||
|
||||
@@ -225,6 +225,7 @@
|
||||
'omit',
|
||||
'pairs',
|
||||
'pick',
|
||||
'transform',
|
||||
'values'
|
||||
];
|
||||
|
||||
@@ -316,6 +317,7 @@
|
||||
'parseInt',
|
||||
'partialRight',
|
||||
'runInContext',
|
||||
'transform',
|
||||
'unzip'
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user