问题
I have this code for a class where I'm supposed to use the reduce() method to find the min and max values in an array. However, we are required to use only a single call to reduce. The return array should be of size 2, but I know that the reduce() method always returns an array of size 1. I'm able to obtain the minimum value using the code below, however I don't know how to obtain the max value in that same call. I assume that once I do obtain the max value that I just push it to the array after the reduce() method finishes.
/**
* Takes an array of numbers and returns an array of size 2,
* where the first element is the smallest element in items,
* and the second element is the largest element in items.
*
* Must do this by using a single call to reduce.
*
* For example, minMax([4, 1, 2, 7, 6]) returns [1, 7]
*/
function minMax(items) {
var minMaxArray = items.reduce(
(accumulator, currentValue) => {
return (accumulator < currentValue ? accumulator : currentValue);
}
);
return minMaxArray;
}
回答1:
The trick consist in provide an empty Array as initialValue Parameter
arr.reduce(callback, [initialValue])
initialValue [Optional] Value to use as the first argument to the first call of the callback. If no initial value is supplied, the first element in the array will be used.
So the code would look like this:
function minMax(items) {
return items.reduce((acc, val) => {
acc[0] = ( acc[0] === undefined || val < acc[0] ) ? val : acc[0]
acc[1] = ( acc[1] === undefined || val > acc[1] ) ? val : acc[1]
return acc;
}, []);
}
回答2:
In ES6 you can use spread operator. One string solution:
Math.min(...items)
回答3:
You can use array as return value:
function minMax(items) {
return items.reduce(
(accumulator, currentValue) => {
return [
Math.min(currentValue, accumulator[0]),
Math.max(currentValue, accumulator[1])
];
}, [Number.MAX_VALUE, Number.MIN_VALUE]
);
}
回答4:
The solution using Math.min() and Math.max() functions:
function minMax(items) {
var minMaxArray = items.reduce(function (r, n) {
r[0] = (!r[0])? n : Math.min(r[0], n);
r[1] = (!r[1])? n : Math.max(r[1], n);
return r;
}, []);
return minMaxArray;
}
console.log(minMax([4, 1, 2, 7, 6]));
回答5:
As the reduce call isn't really needed at all, you could have some fun with it
let items = [62, 3, 7, 9, 33, 6, 322, 67, 853];
let arr = items.reduce((w,o,r,k,s=Math)=>[s.min.apply(0, k),s.max.apply(0, k)],[]);
console.log(arr);
All you'd really need is let minMaxArray = [Math.min.apply(0,items), Math.max.apply(0,items)]
回答6:
To get min and max value of an array using reduce function
const ArrayList = [1, 2, 3, 4, 3, 20, 0];
const LargestNum = ArrayList.reduce((prev, curr) => {
return Math.max(prev, curr)
});
const MinNum = ArrayList.reduce((prev,curr)=>{
return Math.min(pre,curr)
});
console.log(LargestNum);
console.log(MinNum);
回答7:
1. Solution using only Math.min and Math.max:
⚠️
This will not work if you use big arrays, i.e. supply Math.min() with many arguments as "you run the risk of exceeding the JavaScript engine's argument length limit. The consequences of applying a function with too many arguments (think more than tens of thousands of arguments) vary across engines (JavaScriptCore has hard-coded argument limit of 65536), because the limit (indeed even the nature of any excessively-large-stack behavior) is unspecified. Some engines will throw an exception." from MDN web docs.
function minMax(items) {
return [
Math.min.apply(null, items),
Math.max.apply(null, items)
]
}
... or if you prefer ES6's Spread syntax:
const minMax = items => [
Math.min(...items),
Math.max(...items)
]
2. Solution using Array.prototype.reduce, Math.min and Math.max
function minMax(arr) {
return arr.reduce(function(acc, cur) {
return [
Math.min(cur, acc[0]),
Math.max(cur, acc[1])
]
}, [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY]);
}
... or shortened:
const minMax = items =>
items.reduce((acc, cur) =>
[Math.min(cur, acc[0]), Math.max(cur, acc[1])],
[Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY]
)
3. Solution including sensible validations
function minMax(items) {
let newItems = []
const isArray = Array.isArray(items)
const onlyHasNumbers = !items.some(i => isNaN(parseFloat(i)))
// only proceed if items is a non-empty array of numbers
if (isArray && items.length > 0 && onlyHasNumbers) {
newItems = items.reduce(function(acc, cur) {
return [
Math.min(cur, acc[0]),
Math.max(cur, acc[1])
]
}, [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY])
}
return newItems
}
Documentation for Math.min
Documentation for Math.max
Documentation for Array.prototype.reduce()
回答8:
I know this has been answered but I went off of @Sergey Zhukov's answer (which seems incomplete) and was able to get the min and max values in 2 lines:
let vals = [ numeric values ]
let min = Math.min.apply(undefined, vals)
let max = Math.max.apply(undefined, vals)
I do see the value in Array.reduce, but with such a super simple use case, and so long as you understand what Function.apply does, this would be my goto solution.
来源:https://stackoverflow.com/questions/43576241/javascript-using-reduce-to-find-min-and-max-values