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. */
11 var MAX_SAFE_INTEGER = 9007199254740991;
13 /** `Object#toString` result references. */
14 var argsTag = '[object Arguments]',
15 funcTag = '[object Function]',
16 genTag = '[object GeneratorFunction]';
18 /** Detect free variable `global` from Node.js. */
19 var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
21 /** Detect free variable `self`. */
22 var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
24 /** Used as a reference to the global object. */
25 var root = freeGlobal || freeSelf || Function('return this')();
28 * Appends the elements of `values` to `array`.
31 * @param {Array} array The array to modify.
32 * @param {Array} values The values to append.
33 * @returns {Array} Returns `array`.
35 function arrayPush(array, values) {
37 length = values.length,
38 offset = array.length;
40 while (++index < length) {
41 array[offset + index] = values[index];
46 /** Used for built-in method references. */
47 var objectProto = Object.prototype;
49 /** Used to check objects for own properties. */
50 var hasOwnProperty = objectProto.hasOwnProperty;
54 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
57 var objectToString = objectProto.toString;
59 /** Built-in value references. */
60 var Symbol = root.Symbol,
61 propertyIsEnumerable = objectProto.propertyIsEnumerable,
62 spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;
65 * The base implementation of `_.flatten` with support for restricting flattening.
68 * @param {Array} array The array to flatten.
69 * @param {number} depth The maximum recursion depth.
70 * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
71 * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
72 * @param {Array} [result=[]] The initial result value.
73 * @returns {Array} Returns the new flattened array.
75 function baseFlatten(array, depth, predicate, isStrict, result) {
77 length = array.length;
79 predicate || (predicate = isFlattenable);
80 result || (result = []);
82 while (++index < length) {
83 var value = array[index];
84 if (depth > 0 && predicate(value)) {
86 // Recursively flatten arrays (susceptible to call stack limits).
87 baseFlatten(value, depth - 1, predicate, isStrict, result);
89 arrayPush(result, value);
91 } else if (!isStrict) {
92 result[result.length] = value;
99 * Checks if `value` is a flattenable `arguments` object or array.
102 * @param {*} value The value to check.
103 * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
105 function isFlattenable(value) {
106 return isArray(value) || isArguments(value) ||
107 !!(spreadableSymbol && value && value[spreadableSymbol]);
111 * Flattens `array` a single level deep.
117 * @param {Array} array The array to flatten.
118 * @returns {Array} Returns the new flattened array.
121 * _.flatten([1, [2, [3, [4]], 5]]);
122 * // => [1, 2, [3, [4]], 5]
124 function flatten(array) {
125 var length = array ? array.length : 0;
126 return length ? baseFlatten(array, 1) : [];
130 * Checks if `value` is likely an `arguments` object.
136 * @param {*} value The value to check.
137 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
141 * _.isArguments(function() { return arguments; }());
144 * _.isArguments([1, 2, 3]);
147 function isArguments(value) {
148 // Safari 8.1 makes `arguments.callee` enumerable in strict mode.
149 return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
150 (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
154 * Checks if `value` is classified as an `Array` object.
160 * @param {*} value The value to check.
161 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
164 * _.isArray([1, 2, 3]);
167 * _.isArray(document.body.children);
176 var isArray = Array.isArray;
179 * Checks if `value` is array-like. A value is considered array-like if it's
180 * not a function and has a `value.length` that's an integer greater than or
181 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
187 * @param {*} value The value to check.
188 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
191 * _.isArrayLike([1, 2, 3]);
194 * _.isArrayLike(document.body.children);
197 * _.isArrayLike('abc');
200 * _.isArrayLike(_.noop);
203 function isArrayLike(value) {
204 return value != null && isLength(value.length) && !isFunction(value);
208 * This method is like `_.isArrayLike` except that it also checks if `value`
215 * @param {*} value The value to check.
216 * @returns {boolean} Returns `true` if `value` is an array-like object,
220 * _.isArrayLikeObject([1, 2, 3]);
223 * _.isArrayLikeObject(document.body.children);
226 * _.isArrayLikeObject('abc');
229 * _.isArrayLikeObject(_.noop);
232 function isArrayLikeObject(value) {
233 return isObjectLike(value) && isArrayLike(value);
237 * Checks if `value` is classified as a `Function` object.
243 * @param {*} value The value to check.
244 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
250 * _.isFunction(/abc/);
253 function isFunction(value) {
254 // The use of `Object#toString` avoids issues with the `typeof` operator
255 // in Safari 8-9 which returns 'object' for typed array and other constructors.
256 var tag = isObject(value) ? objectToString.call(value) : '';
257 return tag == funcTag || tag == genTag;
261 * Checks if `value` is a valid array-like length.
263 * **Note:** This method is loosely based on
264 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
270 * @param {*} value The value to check.
271 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
277 * _.isLength(Number.MIN_VALUE);
280 * _.isLength(Infinity);
286 function isLength(value) {
287 return typeof value == 'number' &&
288 value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
292 * Checks if `value` is the
293 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
294 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
300 * @param {*} value The value to check.
301 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
307 * _.isObject([1, 2, 3]);
310 * _.isObject(_.noop);
316 function isObject(value) {
317 var type = typeof value;
318 return !!value && (type == 'object' || type == 'function');
322 * Checks if `value` is object-like. A value is object-like if it's not `null`
323 * and has a `typeof` result of "object".
329 * @param {*} value The value to check.
330 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
333 * _.isObjectLike({});
336 * _.isObjectLike([1, 2, 3]);
339 * _.isObjectLike(_.noop);
342 * _.isObjectLike(null);
345 function isObjectLike(value) {
346 return !!value && typeof value == 'object';
349 module.exports = flatten;