2 * lodash (Custom Build) <https://lodash.com/>
3 * Build: `lodash modularize exports="npm" -o ./`
4 * Copyright jQuery Foundation and other contributors <https://jquery.org/>
5 * Released under MIT license <https://lodash.com/license>
6 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
7 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
10 /** Used as references for various `Number` constants. */
12 MAX_SAFE_INTEGER = 9007199254740991;
14 /** `Object#toString` result references. */
15 var argsTag = '[object Arguments]',
16 funcTag = '[object Function]',
17 genTag = '[object GeneratorFunction]',
18 symbolTag = '[object Symbol]';
20 /** Detect free variable `global` from Node.js. */
21 var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
23 /** Detect free variable `self`. */
24 var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
26 /** Used as a reference to the global object. */
27 var root = freeGlobal || freeSelf || Function('return this')();
30 * A faster alternative to `Function#apply`, this function invokes `func`
31 * with the `this` binding of `thisArg` and the arguments of `args`.
34 * @param {Function} func The function to invoke.
35 * @param {*} thisArg The `this` binding of `func`.
36 * @param {Array} args The arguments to invoke `func` with.
37 * @returns {*} Returns the result of `func`.
39 function apply(func, thisArg, args) {
40 switch (args.length) {
41 case 0: return func.call(thisArg);
42 case 1: return func.call(thisArg, args[0]);
43 case 2: return func.call(thisArg, args[0], args[1]);
44 case 3: return func.call(thisArg, args[0], args[1], args[2]);
46 return func.apply(thisArg, args);
50 * A specialized version of `_.map` for arrays without support for iteratee
54 * @param {Array} [array] The array to iterate over.
55 * @param {Function} iteratee The function invoked per iteration.
56 * @returns {Array} Returns the new mapped array.
58 function arrayMap(array, iteratee) {
60 length = array ? array.length : 0,
61 result = Array(length);
63 while (++index < length) {
64 result[index] = iteratee(array[index], index, array);
70 * Appends the elements of `values` to `array`.
73 * @param {Array} array The array to modify.
74 * @param {Array} values The values to append.
75 * @returns {Array} Returns `array`.
77 function arrayPush(array, values) {
79 length = values.length,
80 offset = array.length;
82 while (++index < length) {
83 array[offset + index] = values[index];
88 /** Used for built-in method references. */
89 var objectProto = Object.prototype;
91 /** Used to check objects for own properties. */
92 var hasOwnProperty = objectProto.hasOwnProperty;
96 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
99 var objectToString = objectProto.toString;
101 /** Built-in value references. */
102 var Symbol = root.Symbol,
103 propertyIsEnumerable = objectProto.propertyIsEnumerable,
104 spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;
106 /* Built-in method references for those with the same name as other `lodash` methods. */
107 var nativeMax = Math.max;
110 * The base implementation of `_.flatten` with support for restricting flattening.
113 * @param {Array} array The array to flatten.
114 * @param {number} depth The maximum recursion depth.
115 * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
116 * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
117 * @param {Array} [result=[]] The initial result value.
118 * @returns {Array} Returns the new flattened array.
120 function baseFlatten(array, depth, predicate, isStrict, result) {
122 length = array.length;
124 predicate || (predicate = isFlattenable);
125 result || (result = []);
127 while (++index < length) {
128 var value = array[index];
129 if (depth > 0 && predicate(value)) {
131 // Recursively flatten arrays (susceptible to call stack limits).
132 baseFlatten(value, depth - 1, predicate, isStrict, result);
134 arrayPush(result, value);
136 } else if (!isStrict) {
137 result[result.length] = value;
144 * The base implementation of `_.pick` without support for individual
145 * property identifiers.
148 * @param {Object} object The source object.
149 * @param {string[]} props The property identifiers to pick.
150 * @returns {Object} Returns the new object.
152 function basePick(object, props) {
153 object = Object(object);
154 return basePickBy(object, props, function(value, key) {
155 return key in object;
160 * The base implementation of `_.pickBy` without support for iteratee shorthands.
163 * @param {Object} object The source object.
164 * @param {string[]} props The property identifiers to pick from.
165 * @param {Function} predicate The function invoked per property.
166 * @returns {Object} Returns the new object.
168 function basePickBy(object, props, predicate) {
170 length = props.length,
173 while (++index < length) {
174 var key = props[index],
177 if (predicate(value, key)) {
185 * The base implementation of `_.rest` which doesn't validate or coerce arguments.
188 * @param {Function} func The function to apply a rest parameter to.
189 * @param {number} [start=func.length-1] The start position of the rest parameter.
190 * @returns {Function} Returns the new function.
192 function baseRest(func, start) {
193 start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
195 var args = arguments,
197 length = nativeMax(args.length - start, 0),
198 array = Array(length);
200 while (++index < length) {
201 array[index] = args[start + index];
204 var otherArgs = Array(start + 1);
205 while (++index < start) {
206 otherArgs[index] = args[index];
208 otherArgs[start] = array;
209 return apply(func, this, otherArgs);
214 * Checks if `value` is a flattenable `arguments` object or array.
217 * @param {*} value The value to check.
218 * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
220 function isFlattenable(value) {
221 return isArray(value) || isArguments(value) ||
222 !!(spreadableSymbol && value && value[spreadableSymbol]);
226 * Converts `value` to a string key if it's not a string or symbol.
229 * @param {*} value The value to inspect.
230 * @returns {string|symbol} Returns the key.
232 function toKey(value) {
233 if (typeof value == 'string' || isSymbol(value)) {
236 var result = (value + '');
237 return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
241 * Checks if `value` is likely an `arguments` object.
247 * @param {*} value The value to check.
248 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
252 * _.isArguments(function() { return arguments; }());
255 * _.isArguments([1, 2, 3]);
258 function isArguments(value) {
259 // Safari 8.1 makes `arguments.callee` enumerable in strict mode.
260 return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
261 (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
265 * Checks if `value` is classified as an `Array` object.
271 * @param {*} value The value to check.
272 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
275 * _.isArray([1, 2, 3]);
278 * _.isArray(document.body.children);
287 var isArray = Array.isArray;
290 * Checks if `value` is array-like. A value is considered array-like if it's
291 * not a function and has a `value.length` that's an integer greater than or
292 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
298 * @param {*} value The value to check.
299 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
302 * _.isArrayLike([1, 2, 3]);
305 * _.isArrayLike(document.body.children);
308 * _.isArrayLike('abc');
311 * _.isArrayLike(_.noop);
314 function isArrayLike(value) {
315 return value != null && isLength(value.length) && !isFunction(value);
319 * This method is like `_.isArrayLike` except that it also checks if `value`
326 * @param {*} value The value to check.
327 * @returns {boolean} Returns `true` if `value` is an array-like object,
331 * _.isArrayLikeObject([1, 2, 3]);
334 * _.isArrayLikeObject(document.body.children);
337 * _.isArrayLikeObject('abc');
340 * _.isArrayLikeObject(_.noop);
343 function isArrayLikeObject(value) {
344 return isObjectLike(value) && isArrayLike(value);
348 * Checks if `value` is classified as a `Function` object.
354 * @param {*} value The value to check.
355 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
361 * _.isFunction(/abc/);
364 function isFunction(value) {
365 // The use of `Object#toString` avoids issues with the `typeof` operator
366 // in Safari 8-9 which returns 'object' for typed array and other constructors.
367 var tag = isObject(value) ? objectToString.call(value) : '';
368 return tag == funcTag || tag == genTag;
372 * Checks if `value` is a valid array-like length.
374 * **Note:** This method is loosely based on
375 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
381 * @param {*} value The value to check.
382 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
388 * _.isLength(Number.MIN_VALUE);
391 * _.isLength(Infinity);
397 function isLength(value) {
398 return typeof value == 'number' &&
399 value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
403 * Checks if `value` is the
404 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
405 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
411 * @param {*} value The value to check.
412 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
418 * _.isObject([1, 2, 3]);
421 * _.isObject(_.noop);
427 function isObject(value) {
428 var type = typeof value;
429 return !!value && (type == 'object' || type == 'function');
433 * Checks if `value` is object-like. A value is object-like if it's not `null`
434 * and has a `typeof` result of "object".
440 * @param {*} value The value to check.
441 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
444 * _.isObjectLike({});
447 * _.isObjectLike([1, 2, 3]);
450 * _.isObjectLike(_.noop);
453 * _.isObjectLike(null);
456 function isObjectLike(value) {
457 return !!value && typeof value == 'object';
461 * Checks if `value` is classified as a `Symbol` primitive or object.
467 * @param {*} value The value to check.
468 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
471 * _.isSymbol(Symbol.iterator);
477 function isSymbol(value) {
478 return typeof value == 'symbol' ||
479 (isObjectLike(value) && objectToString.call(value) == symbolTag);
483 * Creates an object composed of the picked `object` properties.
489 * @param {Object} object The source object.
490 * @param {...(string|string[])} [props] The property identifiers to pick.
491 * @returns {Object} Returns the new object.
494 * var object = { 'a': 1, 'b': '2', 'c': 3 };
496 * _.pick(object, ['a', 'c']);
497 * // => { 'a': 1, 'c': 3 }
499 var pick = baseRest(function(object, props) {
500 return object == null ? {} : basePick(object, arrayMap(baseFlatten(props, 1), toKey));
503 module.exports = pick;