For 循环
一般关于实现数组的某种操作,可能最先想到的就是 for
循环吧!下面是它的实现。
let min = arr => {
let greatest = arr[0]
for (let i = 0; i < arr.length; i++) {
if (greatest > arr[i]) {
greatest = arr[i]
}
}
return greatest
}
let max = arr => {
let greatest = 0
for (let i = 0; i < arr.length; i++) {
if (greatest < arr[i]) {
greatest = arr[i]
}
}
return greatest
}
console.log(max(arr)) // 25
console.log(min(arr)) // 1
Math.min()/max()
内置函数 Math.max()
和 Math.min()
可以分别返回一直数中的最大值和最小值,其可以接受任意数量的参数。
Math.max(25, 5, 15, 6, 9, 1, 3) // 25
Math.min(25, 5, 15, 6, 9, 1, 3) // 1
这很方便,但它不能直接用于数组。我们需要一些其他的方法来帮助我们使用它。
call/apply
Function.prototype.apply()
方法调用一个具有给定this
值的函数,以及以一个数组的形式提供的参数。
Function.prototype.call()
方法使用一个指定的 this
值和单独给出的一个或多个参数来调用一个函数。
-
apply()
第二个参数传递arr
数组,使用数组中的所有值作为函数的参数。 -
call()
第二个参数传递arr
数组,并使用扩展运算符,将其展开作为其函数的参数。
let max = arr => Math.max.apply(null, arr)
let min = arr => Math.min.call(null, ...arr)
console.log(max(arr)) // 25
console.log(min(arr)) // 1
扩展运算符
更为简单的方式是,直接使用 ES6 的扩展运算符(...
)展开数组。
console.log(Math.max(...arr)) // 25
console.log(Math.min(...arr)) // 1
Array.prototype.sort()
使用 Array.prototype.sort
先对数组进行排序,在获取数组的第一个元素。
let arr = [25, 5, 15, 6, 9, 1, 3]
let max = arr => arr.sort((a, b) => b - a)[0]
let min = arr => arr.sort((a, b) => a - b)[0]
console.log(max(arr)) // 25
console.log(min(arr)) // 1
如果你还不熟,可以看看 如何在 JavaScript 中对对象数组进行排序?了解 sort()
的用法。
任意数量的最大值
从提供的数组返回 n
个最大元素。
- 使用
Array.prototype.sort()
和扩展运算符(...
)配合,创建数组的浅拷贝,并按降序排序。 - 使用
Array.prototype.slice()
获取指定数量的元素。 - 省略第二个参数
n
,得到一个单元素数组。 - 如果
n
大于或等于提供的数组长度,则返回原始数组(按降序排序)。
const maxN = (arr, n = 1) => [...arr].sort((a, b) => b - a).slice(0, n)
maxN([25, 5, 15, 6, 9, 1, 3]) // [25]
maxN([25, 5, 15, 6, 9, 1, 3], 3) // [25, 15, 9]
任意数量的最小值
从提供的数组返回 n
个最小元素。
- 使用
Array.prototype.sort()
和扩展运算符(...
)配合,创建数组的浅拷贝,并按升序排序。 - 使用
Array.prototype.slice()
获取指定数量的元素。 - 省略第二个参数
n
,得到一个单元素数组。 - 如果
n
大于或等于提供的数组长度,则返回原始数组(按升序排序)。
const minN = (arr, n = 1) => [...arr].sort((a, b) => a - b).slice(0, n)
minN([25, 5, 15, 6, 9, 1, 3]) // [1]
minN([25, 5, 15, 6, 9, 1, 3], 3) // [1, 3, 5]
这两个示例来自 30 seconds of code 的 maxN 和 minN
复杂情况 — 对象数组
对于更复杂的情况(即在对象数组中查找最小/最大值),您可能需要使用 Array.prototype.map()
等一些方法。
最小值
使用提供的函数将每个元素映射到一个值后,返回数组的最小值。
- 使用
Array.prototype.map()
将每个元素映射到fn
所返回的值。 - 使用
Math.min()
获得的最小- 值。
const minBy = (arr, fn) =>
Math.min(...arr.map(typeof fn === 'function' ? fn : val => val[fn]))
minBy([{ n: 4 }, { id: 2 }, { id: 8 }, { id: 6 }], x => x.id) // 2
minBy([{ id: 4 }, { id: 2 }, { id: 8 }, { id: 6 }], 'id') // 2
最大值
使用提供的函数将每个元素映射到一个值后,返回数组的最大值。
- 使用
Array.prototype.map()
将每个元素映射到fn
所返回的值。 - 使用
Math.max()
获取最大值。
const maxBy = (arr, fn) =>
Math.max(...arr.map(typeof fn === 'function' ? fn : val => val[fn]))
maxBy([{ id: 4 }, { id: 2 }, { id: 8 }, { id: 6 }], x => x.id) // 8
maxBy([{ id: 4 }, { id: 2 }, { id: 8 }, { id: 6 }], 'id') // 8