|
3719 | 3719 | * @returns {Array} Returns the new sorted array.
|
3720 | 3720 | */
|
3721 | 3721 | function baseOrderBy(collection, iteratees, orders) {
|
| 3722 | + if (iteratees.length) { |
| 3723 | + iteratees = arrayMap(iteratees, function(iteratee) { |
| 3724 | + if (isArray(iteratee)) { |
| 3725 | + return function(value) { |
| 3726 | + return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee); |
| 3727 | + } |
| 3728 | + } |
| 3729 | + return iteratee; |
| 3730 | + }); |
| 3731 | + } else { |
| 3732 | + iteratees = [identity]; |
| 3733 | + } |
| 3734 | + |
3722 | 3735 | var index = -1;
|
3723 |
| - iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee())); |
| 3736 | + iteratees = arrayMap(iteratees, baseUnary(getIteratee())); |
3724 | 3737 |
|
3725 | 3738 | var result = baseMap(collection, function(value, key, collection) {
|
3726 | 3739 | var criteria = arrayMap(iteratees, function(iteratee) {
|
|
3977 | 3990 | var key = toKey(path[index]),
|
3978 | 3991 | newValue = value;
|
3979 | 3992 |
|
| 3993 | + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { |
| 3994 | + return object; |
| 3995 | + } |
| 3996 | + |
3980 | 3997 | if (index != lastIndex) {
|
3981 | 3998 | var objValue = nested[key];
|
3982 | 3999 | newValue = customizer ? customizer(objValue, key, nested) : undefined;
|
|
4129 | 4146 | * into `array`.
|
4130 | 4147 | */
|
4131 | 4148 | function baseSortedIndexBy(array, value, iteratee, retHighest) {
|
4132 |
| - value = iteratee(value); |
4133 |
| - |
4134 | 4149 | var low = 0,
|
4135 |
| - high = array == null ? 0 : array.length, |
4136 |
| - valIsNaN = value !== value, |
| 4150 | + high = array == null ? 0 : array.length; |
| 4151 | + if (high === 0) { |
| 4152 | + return 0; |
| 4153 | + } |
| 4154 | + |
| 4155 | + value = iteratee(value); |
| 4156 | + var valIsNaN = value !== value, |
4137 | 4157 | valIsNull = value === null,
|
4138 | 4158 | valIsSymbol = isSymbol(value),
|
4139 | 4159 | valIsUndefined = value === undefined;
|
|
5618 | 5638 | if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
|
5619 | 5639 | return false;
|
5620 | 5640 | }
|
5621 |
| - // Assume cyclic values are equal. |
5622 |
| - var stacked = stack.get(array); |
5623 |
| - if (stacked && stack.get(other)) { |
5624 |
| - return stacked == other; |
| 5641 | + // Check that cyclic values are equal. |
| 5642 | + var arrStacked = stack.get(array); |
| 5643 | + var othStacked = stack.get(other); |
| 5644 | + if (arrStacked && othStacked) { |
| 5645 | + return arrStacked == other && othStacked == array; |
5625 | 5646 | }
|
5626 | 5647 | var index = -1,
|
5627 | 5648 | result = true,
|
|
5783 | 5804 | return false;
|
5784 | 5805 | }
|
5785 | 5806 | }
|
5786 |
| - // Assume cyclic values are equal. |
5787 |
| - var stacked = stack.get(object); |
5788 |
| - if (stacked && stack.get(other)) { |
5789 |
| - return stacked == other; |
| 5807 | + // Check that cyclic values are equal. |
| 5808 | + var objStacked = stack.get(object); |
| 5809 | + var othStacked = stack.get(other); |
| 5810 | + if (objStacked && othStacked) { |
| 5811 | + return objStacked == other && othStacked == object; |
5790 | 5812 | }
|
5791 | 5813 | var result = true;
|
5792 | 5814 | stack.set(object, other);
|
|
9167 | 9189 | * // The `_.property` iteratee shorthand.
|
9168 | 9190 | * _.filter(users, 'active');
|
9169 | 9191 | * // => objects for ['barney']
|
| 9192 | + * |
| 9193 | + * // Combining several predicates using `_.overEvery` or `_.overSome`. |
| 9194 | + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); |
| 9195 | + * // => objects for ['fred', 'barney'] |
9170 | 9196 | */
|
9171 | 9197 | function filter(collection, predicate) {
|
9172 | 9198 | var func = isArray(collection) ? arrayFilter : baseFilter;
|
|
9916 | 9942 | * var users = [
|
9917 | 9943 | * { 'user': 'fred', 'age': 48 },
|
9918 | 9944 | * { 'user': 'barney', 'age': 36 },
|
9919 |
| - * { 'user': 'fred', 'age': 40 }, |
| 9945 | + * { 'user': 'fred', 'age': 30 }, |
9920 | 9946 | * { 'user': 'barney', 'age': 34 }
|
9921 | 9947 | * ];
|
9922 | 9948 | *
|
9923 | 9949 | * _.sortBy(users, [function(o) { return o.user; }]);
|
9924 |
| - * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] |
| 9950 | + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] |
9925 | 9951 | *
|
9926 | 9952 | * _.sortBy(users, ['user', 'age']);
|
9927 |
| - * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]] |
| 9953 | + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] |
9928 | 9954 | */
|
9929 | 9955 | var sortBy = baseRest(function(collection, iteratees) {
|
9930 | 9956 | if (collection == null) {
|
@@ -14799,11 +14825,11 @@
|
14799 | 14825 |
|
14800 | 14826 | // Use a sourceURL for easier debugging.
|
14801 | 14827 | // The sourceURL gets injected into the source that's eval-ed, so be careful
|
14802 |
| - // with lookup (in case of e.g. prototype pollution), and strip newlines if any. |
14803 |
| - // A newline wouldn't be a valid sourceURL anyway, and it'd enable code injection. |
| 14828 | + // to normalize all kinds of whitespace, so e.g. newlines (and unicode versions of it) can't sneak in |
| 14829 | + // and escape the comment, thus injecting code that gets evaled. |
14804 | 14830 | var sourceURL = '//# sourceURL=' +
|
14805 | 14831 | (hasOwnProperty.call(options, 'sourceURL')
|
14806 |
| - ? (options.sourceURL + '').replace(/[\r\n]/g, ' ') |
| 14832 | + ? (options.sourceURL + '').replace(/\s/g, ' ') |
14807 | 14833 | : ('lodash.templateSources[' + (++templateCounter) + ']')
|
14808 | 14834 | ) + '\n';
|
14809 | 14835 |
|
|
14836 | 14862 |
|
14837 | 14863 | // If `variable` is not specified wrap a with-statement around the generated
|
14838 | 14864 | // code to add the data object to the top of the scope chain.
|
14839 |
| - // Like with sourceURL, we take care to not check the option's prototype, |
14840 |
| - // as this configuration is a code injection vector. |
14841 | 14865 | var variable = hasOwnProperty.call(options, 'variable') && options.variable;
|
14842 | 14866 | if (!variable) {
|
14843 | 14867 | source = 'with (obj) {\n' + source + '\n}\n';
|
|
15544 | 15568 | * values against any array or object value, respectively. See `_.isEqual`
|
15545 | 15569 | * for a list of supported value comparisons.
|
15546 | 15570 | *
|
| 15571 | + * **Note:** Multiple values can be checked by combining several matchers |
| 15572 | + * using `_.overSome` |
| 15573 | + * |
15547 | 15574 | * @static
|
15548 | 15575 | * @memberOf _
|
15549 | 15576 | * @since 3.0.0
|
|
15559 | 15586 | *
|
15560 | 15587 | * _.filter(objects, _.matches({ 'a': 4, 'c': 6 }));
|
15561 | 15588 | * // => [{ 'a': 4, 'b': 5, 'c': 6 }]
|
| 15589 | + * |
| 15590 | + * // Checking for several possible values |
| 15591 | + * _.filter(users, _.overSome([_.matches({ 'a': 1 }), _.matches({ 'a': 4 })])); |
| 15592 | + * // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }] |
15562 | 15593 | */
|
15563 | 15594 | function matches(source) {
|
15564 | 15595 | return baseMatches(baseClone(source, CLONE_DEEP_FLAG));
|
|
15573 | 15604 | * `srcValue` values against any array or object value, respectively. See
|
15574 | 15605 | * `_.isEqual` for a list of supported value comparisons.
|
15575 | 15606 | *
|
| 15607 | + * **Note:** Multiple values can be checked by combining several matchers |
| 15608 | + * using `_.overSome` |
| 15609 | + * |
15576 | 15610 | * @static
|
15577 | 15611 | * @memberOf _
|
15578 | 15612 | * @since 3.2.0
|
|
15589 | 15623 | *
|
15590 | 15624 | * _.find(objects, _.matchesProperty('a', 4));
|
15591 | 15625 | * // => { 'a': 4, 'b': 5, 'c': 6 }
|
| 15626 | + * |
| 15627 | + * // Checking for several possible values |
| 15628 | + * _.filter(users, _.overSome([_.matchesProperty('a', 1), _.matchesProperty('a', 4)])); |
| 15629 | + * // => [{ 'a': 1, 'b': 2, 'c': 3 }, { 'a': 4, 'b': 5, 'c': 6 }] |
15592 | 15630 | */
|
15593 | 15631 | function matchesProperty(path, srcValue) {
|
15594 | 15632 | return baseMatchesProperty(path, baseClone(srcValue, CLONE_DEEP_FLAG));
|
|
15812 | 15850 | * Creates a function that checks if **all** of the `predicates` return
|
15813 | 15851 | * truthy when invoked with the arguments it receives.
|
15814 | 15852 | *
|
| 15853 | + * Following shorthands are possible for providing predicates. |
| 15854 | + * Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate. |
| 15855 | + * Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them. |
| 15856 | + * |
15815 | 15857 | * @static
|
15816 | 15858 | * @memberOf _
|
15817 | 15859 | * @since 4.0.0
|
|
15838 | 15880 | * Creates a function that checks if **any** of the `predicates` return
|
15839 | 15881 | * truthy when invoked with the arguments it receives.
|
15840 | 15882 | *
|
| 15883 | + * Following shorthands are possible for providing predicates. |
| 15884 | + * Pass an `Object` and it will be used as an parameter for `_.matches` to create the predicate. |
| 15885 | + * Pass an `Array` of parameters for `_.matchesProperty` and the predicate will be created using them. |
| 15886 | + * |
15841 | 15887 | * @static
|
15842 | 15888 | * @memberOf _
|
15843 | 15889 | * @since 4.0.0
|
|
15857 | 15903 | *
|
15858 | 15904 | * func(NaN);
|
15859 | 15905 | * // => false
|
| 15906 | + * |
| 15907 | + * var matchesFunc = _.overSome([{ 'a': 1 }, { 'a': 2 }]) |
| 15908 | + * var matchesPropertyFunc = _.overSome([['a', 1], ['a', 2]]) |
15860 | 15909 | */
|
15861 | 15910 | var overSome = createOver(arraySome);
|
15862 | 15911 |
|
|
0 commit comments