1 | /**
|
2 | * lodash 4.1.0 (Custom Build) <https://lodash.com/>
|
3 | * Build: `lodash modularize exports="npm" -o ./`
|
4 | * Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
|
5 | * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
6 | * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
7 | * Available under MIT license <https://lodash.com/license>
|
8 | */
|
9 | var baseIsEqual = require('lodash._baseisequal'),
|
10 | baseIsMatch = require('lodash._baseismatch'),
|
11 | get = require('lodash.get'),
|
12 | hasIn = require('lodash.hasin'),
|
13 | root = require('lodash._root'),
|
14 | toPairs = require('lodash.topairs');
|
15 |
|
16 | /** Used to compose bitmasks for comparison styles. */
|
17 | var UNORDERED_COMPARE_FLAG = 1,
|
18 | PARTIAL_COMPARE_FLAG = 2;
|
19 |
|
20 | /** Used as references for various `Number` constants. */
|
21 | var INFINITY = 1 / 0;
|
22 |
|
23 | /** `Object#toString` result references. */
|
24 | var symbolTag = '[object Symbol]';
|
25 |
|
26 | /** Used to match property names within property paths. */
|
27 | var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
|
28 | reIsPlainProp = /^\w*$/,
|
29 | rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
|
30 |
|
31 | /** Used to match backslashes in property paths. */
|
32 | var reEscapeChar = /\\(\\)?/g;
|
33 |
|
34 | /**
|
35 | * The base implementation of methods like `_.max` and `_.min` which accepts a
|
36 | * `comparator` to determine the extremum value.
|
37 | *
|
38 | * @private
|
39 | * @param {Array} array The array to iterate over.
|
40 | * @param {Function} iteratee The iteratee invoked per iteration.
|
41 | * @param {Function} comparator The comparator used to compare values.
|
42 | * @returns {*} Returns the extremum value.
|
43 | */
|
44 | function baseExtremum(array, iteratee, comparator) {
|
45 | var index = -1,
|
46 | length = array.length;
|
47 |
|
48 | while (++index < length) {
|
49 | var value = array[index],
|
50 | current = iteratee(value);
|
51 |
|
52 | if (current != null && (computed === undefined
|
53 | ? current === current
|
54 | : comparator(current, computed)
|
55 | )) {
|
56 | var computed = current,
|
57 | result = value;
|
58 | }
|
59 | }
|
60 | return result;
|
61 | }
|
62 |
|
63 | /** Used for built-in method references. */
|
64 | var objectProto = Object.prototype;
|
65 |
|
66 | /**
|
67 | * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
68 | * of values.
|
69 | */
|
70 | var objectToString = objectProto.toString;
|
71 |
|
72 | /** Built-in value references. */
|
73 | var Symbol = root.Symbol;
|
74 |
|
75 | /** Used to convert symbols to primitives and strings. */
|
76 | var symbolProto = Symbol ? Symbol.prototype : undefined,
|
77 | symbolToString = Symbol ? symbolProto.toString : undefined;
|
78 |
|
79 | /**
|
80 | * The base implementation of `_.get` without support for default values.
|
81 | *
|
82 | * @private
|
83 | * @param {Object} object The object to query.
|
84 | * @param {Array|string} path The path of the property to get.
|
85 | * @returns {*} Returns the resolved value.
|
86 | */
|
87 | function baseGet(object, path) {
|
88 | path = isKey(path, object) ? [path + ''] : baseToPath(path);
|
89 |
|
90 | var index = 0,
|
91 | length = path.length;
|
92 |
|
93 | while (object != null && index < length) {
|
94 | object = object[path[index++]];
|
95 | }
|
96 | return (index && index == length) ? object : undefined;
|
97 | }
|
98 |
|
99 | /**
|
100 | * The base implementation of `_.iteratee`.
|
101 | *
|
102 | * @private
|
103 | * @param {*} [value=_.identity] The value to convert to an iteratee.
|
104 | * @returns {Function} Returns the iteratee.
|
105 | */
|
106 | function baseIteratee(value) {
|
107 | var type = typeof value;
|
108 | if (type == 'function') {
|
109 | return value;
|
110 | }
|
111 | if (value == null) {
|
112 | return identity;
|
113 | }
|
114 | if (type == 'object') {
|
115 | return isArray(value)
|
116 | ? baseMatchesProperty(value[0], value[1])
|
117 | : baseMatches(value);
|
118 | }
|
119 | return property(value);
|
120 | }
|
121 |
|
122 | /**
|
123 | * The base implementation of `_.matches` which doesn't clone `source`.
|
124 | *
|
125 | * @private
|
126 | * @param {Object} source The object of property values to match.
|
127 | * @returns {Function} Returns the new function.
|
128 | */
|
129 | function baseMatches(source) {
|
130 | var matchData = getMatchData(source);
|
131 | if (matchData.length == 1 && matchData[0][2]) {
|
132 | var key = matchData[0][0],
|
133 | value = matchData[0][1];
|
134 |
|
135 | return function(object) {
|
136 | if (object == null) {
|
137 | return false;
|
138 | }
|
139 | return object[key] === value &&
|
140 | (value !== undefined || (key in Object(object)));
|
141 | };
|
142 | }
|
143 | return function(object) {
|
144 | return object === source || baseIsMatch(object, source, matchData);
|
145 | };
|
146 | }
|
147 |
|
148 | /**
|
149 | * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
|
150 | *
|
151 | * @private
|
152 | * @param {string} path The path of the property to get.
|
153 | * @param {*} srcValue The value to match.
|
154 | * @returns {Function} Returns the new function.
|
155 | */
|
156 | function baseMatchesProperty(path, srcValue) {
|
157 | return function(object) {
|
158 | var objValue = get(object, path);
|
159 | return (objValue === undefined && objValue === srcValue)
|
160 | ? hasIn(object, path)
|
161 | : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);
|
162 | };
|
163 | }
|
164 |
|
165 | /**
|
166 | * The base implementation of `_.property` without support for deep paths.
|
167 | *
|
168 | * @private
|
169 | * @param {string} key The key of the property to get.
|
170 | * @returns {Function} Returns the new function.
|
171 | */
|
172 | function baseProperty(key) {
|
173 | return function(object) {
|
174 | return object == null ? undefined : object[key];
|
175 | };
|
176 | }
|
177 |
|
178 | /**
|
179 | * A specialized version of `baseProperty` which supports deep paths.
|
180 | *
|
181 | * @private
|
182 | * @param {Array|string} path The path of the property to get.
|
183 | * @returns {Function} Returns the new function.
|
184 | */
|
185 | function basePropertyDeep(path) {
|
186 | return function(object) {
|
187 | return baseGet(object, path);
|
188 | };
|
189 | }
|
190 |
|
191 | /**
|
192 | * The base implementation of `_.toPath` which only converts `value` to a
|
193 | * path if it's not one.
|
194 | *
|
195 | * @private
|
196 | * @param {*} value The value to process.
|
197 | * @returns {Array} Returns the property path array.
|
198 | */
|
199 | function baseToPath(value) {
|
200 | return isArray(value) ? value : stringToPath(value);
|
201 | }
|
202 |
|
203 | /**
|
204 | * Gets the property names, values, and compare flags of `object`.
|
205 | *
|
206 | * @private
|
207 | * @param {Object} object The object to query.
|
208 | * @returns {Array} Returns the match data of `object`.
|
209 | */
|
210 | function getMatchData(object) {
|
211 | var result = toPairs(object),
|
212 | length = result.length;
|
213 |
|
214 | while (length--) {
|
215 | result[length][2] = isStrictComparable(result[length][1]);
|
216 | }
|
217 | return result;
|
218 | }
|
219 |
|
220 | /**
|
221 | * Checks if `value` is a property name and not a property path.
|
222 | *
|
223 | * @private
|
224 | * @param {*} value The value to check.
|
225 | * @param {Object} [object] The object to query keys on.
|
226 | * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
|
227 | */
|
228 | function isKey(value, object) {
|
229 | if (typeof value == 'number') {
|
230 | return true;
|
231 | }
|
232 | return !isArray(value) &&
|
233 | (reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
|
234 | (object != null && value in Object(object)));
|
235 | }
|
236 |
|
237 | /**
|
238 | * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
|
239 | *
|
240 | * @private
|
241 | * @param {*} value The value to check.
|
242 | * @returns {boolean} Returns `true` if `value` if suitable for strict
|
243 | * equality comparisons, else `false`.
|
244 | */
|
245 | function isStrictComparable(value) {
|
246 | return value === value && !isObject(value);
|
247 | }
|
248 |
|
249 | /**
|
250 | * Converts `string` to a property path array.
|
251 | *
|
252 | * @private
|
253 | * @param {string} string The string to convert.
|
254 | * @returns {Array} Returns the property path array.
|
255 | */
|
256 | function stringToPath(string) {
|
257 | var result = [];
|
258 | toString(string).replace(rePropName, function(match, number, quote, string) {
|
259 | result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
|
260 | });
|
261 | return result;
|
262 | }
|
263 |
|
264 | /**
|
265 | * Checks if `value` is classified as an `Array` object.
|
266 | *
|
267 | * @static
|
268 | * @memberOf _
|
269 | * @type Function
|
270 | * @category Lang
|
271 | * @param {*} value The value to check.
|
272 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
273 | * @example
|
274 | *
|
275 | * _.isArray([1, 2, 3]);
|
276 | * // => true
|
277 | *
|
278 | * _.isArray(document.body.children);
|
279 | * // => false
|
280 | *
|
281 | * _.isArray('abc');
|
282 | * // => false
|
283 | *
|
284 | * _.isArray(_.noop);
|
285 | * // => false
|
286 | */
|
287 | var isArray = Array.isArray;
|
288 |
|
289 | /**
|
290 | * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
|
291 | * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
292 | *
|
293 | * @static
|
294 | * @memberOf _
|
295 | * @category Lang
|
296 | * @param {*} value The value to check.
|
297 | * @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
298 | * @example
|
299 | *
|
300 | * _.isObject({});
|
301 | * // => true
|
302 | *
|
303 | * _.isObject([1, 2, 3]);
|
304 | * // => true
|
305 | *
|
306 | * _.isObject(_.noop);
|
307 | * // => true
|
308 | *
|
309 | * _.isObject(null);
|
310 | * // => false
|
311 | */
|
312 | function isObject(value) {
|
313 | var type = typeof value;
|
314 | return !!value && (type == 'object' || type == 'function');
|
315 | }
|
316 |
|
317 | /**
|
318 | * Checks if `value` is object-like. A value is object-like if it's not `null`
|
319 | * and has a `typeof` result of "object".
|
320 | *
|
321 | * @static
|
322 | * @memberOf _
|
323 | * @category Lang
|
324 | * @param {*} value The value to check.
|
325 | * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
326 | * @example
|
327 | *
|
328 | * _.isObjectLike({});
|
329 | * // => true
|
330 | *
|
331 | * _.isObjectLike([1, 2, 3]);
|
332 | * // => true
|
333 | *
|
334 | * _.isObjectLike(_.noop);
|
335 | * // => false
|
336 | *
|
337 | * _.isObjectLike(null);
|
338 | * // => false
|
339 | */
|
340 | function isObjectLike(value) {
|
341 | return !!value && typeof value == 'object';
|
342 | }
|
343 |
|
344 | /**
|
345 | * Checks if `value` is classified as a `Symbol` primitive or object.
|
346 | *
|
347 | * @static
|
348 | * @memberOf _
|
349 | * @category Lang
|
350 | * @param {*} value The value to check.
|
351 | * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
352 | * @example
|
353 | *
|
354 | * _.isSymbol(Symbol.iterator);
|
355 | * // => true
|
356 | *
|
357 | * _.isSymbol('abc');
|
358 | * // => false
|
359 | */
|
360 | function isSymbol(value) {
|
361 | return typeof value == 'symbol' ||
|
362 | (isObjectLike(value) && objectToString.call(value) == symbolTag);
|
363 | }
|
364 |
|
365 | /**
|
366 | * Checks if `value` is less than `other`.
|
367 | *
|
368 | * @static
|
369 | * @memberOf _
|
370 | * @category Lang
|
371 | * @param {*} value The value to compare.
|
372 | * @param {*} other The other value to compare.
|
373 | * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`.
|
374 | * @example
|
375 | *
|
376 | * _.lt(1, 3);
|
377 | * // => true
|
378 | *
|
379 | * _.lt(3, 3);
|
380 | * // => false
|
381 | *
|
382 | * _.lt(3, 1);
|
383 | * // => false
|
384 | */
|
385 | function lt(value, other) {
|
386 | return value < other;
|
387 | }
|
388 |
|
389 | /**
|
390 | * Converts `value` to a string if it's not one. An empty string is returned
|
391 | * for `null` and `undefined` values. The sign of `-0` is preserved.
|
392 | *
|
393 | * @static
|
394 | * @memberOf _
|
395 | * @category Lang
|
396 | * @param {*} value The value to process.
|
397 | * @returns {string} Returns the string.
|
398 | * @example
|
399 | *
|
400 | * _.toString(null);
|
401 | * // => ''
|
402 | *
|
403 | * _.toString(-0);
|
404 | * // => '-0'
|
405 | *
|
406 | * _.toString([1, 2, 3]);
|
407 | * // => '1,2,3'
|
408 | */
|
409 | function toString(value) {
|
410 | // Exit early for strings to avoid a performance hit in some environments.
|
411 | if (typeof value == 'string') {
|
412 | return value;
|
413 | }
|
414 | if (value == null) {
|
415 | return '';
|
416 | }
|
417 | if (isSymbol(value)) {
|
418 | return Symbol ? symbolToString.call(value) : '';
|
419 | }
|
420 | var result = (value + '');
|
421 | return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
|
422 | }
|
423 |
|
424 | /**
|
425 | * This method returns the first argument provided to it.
|
426 | *
|
427 | * @static
|
428 | * @memberOf _
|
429 | * @category Util
|
430 | * @param {*} value Any value.
|
431 | * @returns {*} Returns `value`.
|
432 | * @example
|
433 | *
|
434 | * var object = { 'user': 'fred' };
|
435 | *
|
436 | * _.identity(object) === object;
|
437 | * // => true
|
438 | */
|
439 | function identity(value) {
|
440 | return value;
|
441 | }
|
442 |
|
443 | /**
|
444 | * Creates a function that returns the value at `path` of a given object.
|
445 | *
|
446 | * @static
|
447 | * @memberOf _
|
448 | * @category Util
|
449 | * @param {Array|string} path The path of the property to get.
|
450 | * @returns {Function} Returns the new function.
|
451 | * @example
|
452 | *
|
453 | * var objects = [
|
454 | * { 'a': { 'b': { 'c': 2 } } },
|
455 | * { 'a': { 'b': { 'c': 1 } } }
|
456 | * ];
|
457 | *
|
458 | * _.map(objects, _.property('a.b.c'));
|
459 | * // => [2, 1]
|
460 | *
|
461 | * _.map(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
|
462 | * // => [1, 2]
|
463 | */
|
464 | function property(path) {
|
465 | return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
|
466 | }
|
467 |
|
468 | /**
|
469 | * This method is like `_.min` except that it accepts `iteratee` which is
|
470 | * invoked for each element in `array` to generate the criterion by which
|
471 | * the value is ranked. The iteratee is invoked with one argument: (value).
|
472 | *
|
473 | * @static
|
474 | * @memberOf _
|
475 | * @category Math
|
476 | * @param {Array} array The array to iterate over.
|
477 | * @param {Function|Object|string} [iteratee=_.identity] The iteratee invoked per element.
|
478 | * @returns {*} Returns the minimum value.
|
479 | * @example
|
480 | *
|
481 | * var objects = [{ 'n': 1 }, { 'n': 2 }];
|
482 | *
|
483 | * _.minBy(objects, function(o) { return o.n; });
|
484 | * // => { 'n': 1 }
|
485 | *
|
486 | * // The `_.property` iteratee shorthand.
|
487 | * _.minBy(objects, 'n');
|
488 | * // => { 'n': 1 }
|
489 | */
|
490 | function minBy(array, iteratee) {
|
491 | return (array && array.length)
|
492 | ? baseExtremum(array, baseIteratee(iteratee), lt)
|
493 | : undefined;
|
494 | }
|
495 |
|
496 | module.exports = minBy;
|