Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

349 рядки
8.7 KiB

3 роки тому
  1. /**
  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
  8. */
  9. /** Used as references for various `Number` constants. */
  10. var MAX_SAFE_INTEGER = 9007199254740991;
  11. /** `Object#toString` result references. */
  12. var argsTag = '[object Arguments]',
  13. funcTag = '[object Function]',
  14. genTag = '[object GeneratorFunction]';
  15. /** Detect free variable `global` from Node.js. */
  16. var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
  17. /** Detect free variable `self`. */
  18. var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
  19. /** Used as a reference to the global object. */
  20. var root = freeGlobal || freeSelf || Function('return this')();
  21. /**
  22. * Appends the elements of `values` to `array`.
  23. *
  24. * @private
  25. * @param {Array} array The array to modify.
  26. * @param {Array} values The values to append.
  27. * @returns {Array} Returns `array`.
  28. */
  29. function arrayPush(array, values) {
  30. var index = -1,
  31. length = values.length,
  32. offset = array.length;
  33. while (++index < length) {
  34. array[offset + index] = values[index];
  35. }
  36. return array;
  37. }
  38. /** Used for built-in method references. */
  39. var objectProto = Object.prototype;
  40. /** Used to check objects for own properties. */
  41. var hasOwnProperty = objectProto.hasOwnProperty;
  42. /**
  43. * Used to resolve the
  44. * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
  45. * of values.
  46. */
  47. var objectToString = objectProto.toString;
  48. /** Built-in value references. */
  49. var Symbol = root.Symbol,
  50. propertyIsEnumerable = objectProto.propertyIsEnumerable,
  51. spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;
  52. /**
  53. * The base implementation of `_.flatten` with support for restricting flattening.
  54. *
  55. * @private
  56. * @param {Array} array The array to flatten.
  57. * @param {number} depth The maximum recursion depth.
  58. * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
  59. * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
  60. * @param {Array} [result=[]] The initial result value.
  61. * @returns {Array} Returns the new flattened array.
  62. */
  63. function baseFlatten(array, depth, predicate, isStrict, result) {
  64. var index = -1,
  65. length = array.length;
  66. predicate || (predicate = isFlattenable);
  67. result || (result = []);
  68. while (++index < length) {
  69. var value = array[index];
  70. if (depth > 0 && predicate(value)) {
  71. if (depth > 1) {
  72. // Recursively flatten arrays (susceptible to call stack limits).
  73. baseFlatten(value, depth - 1, predicate, isStrict, result);
  74. } else {
  75. arrayPush(result, value);
  76. }
  77. } else if (!isStrict) {
  78. result[result.length] = value;
  79. }
  80. }
  81. return result;
  82. }
  83. /**
  84. * Checks if `value` is a flattenable `arguments` object or array.
  85. *
  86. * @private
  87. * @param {*} value The value to check.
  88. * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
  89. */
  90. function isFlattenable(value) {
  91. return isArray(value) || isArguments(value) ||
  92. !!(spreadableSymbol && value && value[spreadableSymbol]);
  93. }
  94. /**
  95. * Flattens `array` a single level deep.
  96. *
  97. * @static
  98. * @memberOf _
  99. * @since 0.1.0
  100. * @category Array
  101. * @param {Array} array The array to flatten.
  102. * @returns {Array} Returns the new flattened array.
  103. * @example
  104. *
  105. * _.flatten([1, [2, [3, [4]], 5]]);
  106. * // => [1, 2, [3, [4]], 5]
  107. */
  108. function flatten(array) {
  109. var length = array ? array.length : 0;
  110. return length ? baseFlatten(array, 1) : [];
  111. }
  112. /**
  113. * Checks if `value` is likely an `arguments` object.
  114. *
  115. * @static
  116. * @memberOf _
  117. * @since 0.1.0
  118. * @category Lang
  119. * @param {*} value The value to check.
  120. * @returns {boolean} Returns `true` if `value` is an `arguments` object,
  121. * else `false`.
  122. * @example
  123. *
  124. * _.isArguments(function() { return arguments; }());
  125. * // => true
  126. *
  127. * _.isArguments([1, 2, 3]);
  128. * // => false
  129. */
  130. function isArguments(value) {
  131. // Safari 8.1 makes `arguments.callee` enumerable in strict mode.
  132. return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
  133. (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
  134. }
  135. /**
  136. * Checks if `value` is classified as an `Array` object.
  137. *
  138. * @static
  139. * @memberOf _
  140. * @since 0.1.0
  141. * @category Lang
  142. * @param {*} value The value to check.
  143. * @returns {boolean} Returns `true` if `value` is an array, else `false`.
  144. * @example
  145. *
  146. * _.isArray([1, 2, 3]);
  147. * // => true
  148. *
  149. * _.isArray(document.body.children);
  150. * // => false
  151. *
  152. * _.isArray('abc');
  153. * // => false
  154. *
  155. * _.isArray(_.noop);
  156. * // => false
  157. */
  158. var isArray = Array.isArray;
  159. /**
  160. * Checks if `value` is array-like. A value is considered array-like if it's
  161. * not a function and has a `value.length` that's an integer greater than or
  162. * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
  163. *
  164. * @static
  165. * @memberOf _
  166. * @since 4.0.0
  167. * @category Lang
  168. * @param {*} value The value to check.
  169. * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
  170. * @example
  171. *
  172. * _.isArrayLike([1, 2, 3]);
  173. * // => true
  174. *
  175. * _.isArrayLike(document.body.children);
  176. * // => true
  177. *
  178. * _.isArrayLike('abc');
  179. * // => true
  180. *
  181. * _.isArrayLike(_.noop);
  182. * // => false
  183. */
  184. function isArrayLike(value) {
  185. return value != null && isLength(value.length) && !isFunction(value);
  186. }
  187. /**
  188. * This method is like `_.isArrayLike` except that it also checks if `value`
  189. * is an object.
  190. *
  191. * @static
  192. * @memberOf _
  193. * @since 4.0.0
  194. * @category Lang
  195. * @param {*} value The value to check.
  196. * @returns {boolean} Returns `true` if `value` is an array-like object,
  197. * else `false`.
  198. * @example
  199. *
  200. * _.isArrayLikeObject([1, 2, 3]);
  201. * // => true
  202. *
  203. * _.isArrayLikeObject(document.body.children);
  204. * // => true
  205. *
  206. * _.isArrayLikeObject('abc');
  207. * // => false
  208. *
  209. * _.isArrayLikeObject(_.noop);
  210. * // => false
  211. */
  212. function isArrayLikeObject(value) {
  213. return isObjectLike(value) && isArrayLike(value);
  214. }
  215. /**
  216. * Checks if `value` is classified as a `Function` object.
  217. *
  218. * @static
  219. * @memberOf _
  220. * @since 0.1.0
  221. * @category Lang
  222. * @param {*} value The value to check.
  223. * @returns {boolean} Returns `true` if `value` is a function, else `false`.
  224. * @example
  225. *
  226. * _.isFunction(_);
  227. * // => true
  228. *
  229. * _.isFunction(/abc/);
  230. * // => false
  231. */
  232. function isFunction(value) {
  233. // The use of `Object#toString` avoids issues with the `typeof` operator
  234. // in Safari 8-9 which returns 'object' for typed array and other constructors.
  235. var tag = isObject(value) ? objectToString.call(value) : '';
  236. return tag == funcTag || tag == genTag;
  237. }
  238. /**
  239. * Checks if `value` is a valid array-like length.
  240. *
  241. * **Note:** This method is loosely based on
  242. * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
  243. *
  244. * @static
  245. * @memberOf _
  246. * @since 4.0.0
  247. * @category Lang
  248. * @param {*} value The value to check.
  249. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
  250. * @example
  251. *
  252. * _.isLength(3);
  253. * // => true
  254. *
  255. * _.isLength(Number.MIN_VALUE);
  256. * // => false
  257. *
  258. * _.isLength(Infinity);
  259. * // => false
  260. *
  261. * _.isLength('3');
  262. * // => false
  263. */
  264. function isLength(value) {
  265. return typeof value == 'number' &&
  266. value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
  267. }
  268. /**
  269. * Checks if `value` is the
  270. * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
  271. * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  272. *
  273. * @static
  274. * @memberOf _
  275. * @since 0.1.0
  276. * @category Lang
  277. * @param {*} value The value to check.
  278. * @returns {boolean} Returns `true` if `value` is an object, else `false`.
  279. * @example
  280. *
  281. * _.isObject({});
  282. * // => true
  283. *
  284. * _.isObject([1, 2, 3]);
  285. * // => true
  286. *
  287. * _.isObject(_.noop);
  288. * // => true
  289. *
  290. * _.isObject(null);
  291. * // => false
  292. */
  293. function isObject(value) {
  294. var type = typeof value;
  295. return !!value && (type == 'object' || type == 'function');
  296. }
  297. /**
  298. * Checks if `value` is object-like. A value is object-like if it's not `null`
  299. * and has a `typeof` result of "object".
  300. *
  301. * @static
  302. * @memberOf _
  303. * @since 4.0.0
  304. * @category Lang
  305. * @param {*} value The value to check.
  306. * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
  307. * @example
  308. *
  309. * _.isObjectLike({});
  310. * // => true
  311. *
  312. * _.isObjectLike([1, 2, 3]);
  313. * // => true
  314. *
  315. * _.isObjectLike(_.noop);
  316. * // => false
  317. *
  318. * _.isObjectLike(null);
  319. * // => false
  320. */
  321. function isObjectLike(value) {
  322. return !!value && typeof value == 'object';
  323. }
  324. module.exports = flatten;