# 数组转对象
通用方法
const arr = [['name', 'Alice'], ['age', 30]] | |
const obj = Object.fromEntries(arr) |
将数组转换为对象最快的方法
var person = ['arrary', 'number', 'string'] | |
console.log({...person}) // {0: "arrary", 1: "number", 2: "string"} |
# 生成数组
当你需要要生成一个 0-99 的数组
# 方案 1
const createArr = (n) => Array.from(new Array(n), (v, i) => i) | |
const arr = createArr(100) // 0 - 99 数组 |
# 方案 2
const createArr = (n) => new Array(n).fill(0).map((v, i) => i) | |
createArr(100) // 0 - 99 数组 |
# 数组合并
你知道在不使用 concat()
方法将数组合并为一个数组嘛?有一种简单的方法可以将任意数量的数组合并。
var arr1 = [1,2,3,4] | |
var arr2 = [5,6,7,8] | |
var arr3 = [9,10] | |
console.log([...arr1, ...arr2, ...arr3]) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] |
# 数组去重
数组去重可以说是面试中最常见的一个问题了,这里有一个快速且简单的解决方案,我们可以使用 new Set()
来去重。下面为你展示两中使用 new Set()
去重的方法。
var num = [1, 1, 2, 2, 3, 4, 5, 3, 2] | |
// First method | |
console.log(Array.from(new Set(num))); // returns [1, 2, 3, 4, 5] | |
// Second method | |
console.log([...new Set(num)]); // returns [1, 2, 3, 4, 5] |
# 数组清空
你是否有一个充满元素的数组,但是处于某种原因你需要清空它,我们有另外一中清空数组的方法。
var num = [1, 2, 3, 4] | |
num.length = 0 | |
console.log(num) // [] |
# 数组填充
在某些情况下,当我们创建一个数组时,我们想用一些数据填充它,我们可以使用 fill()
。
var newArray = new Array(10).fill("1"); | |
console.log(newArray) // ["1", "1", "1", "1", "1", "1", "1", "1", "1", "1"] |
# 数组打乱
当你有一个数组,你需要打乱这个数组的排序
const randomSort = list => list.sort(() => Math.random() - 0.5) | |
randomSort([0,1,2,3,4,5,6,7,8,9]) // 随机排列结果 |
# 数组取交集
当你需要取多个数组中的交集
const intersection = (a, ...arr) => [...new Set(a)].filter((v) => arr.every((b) => b.includes(v))) | |
intersection([1, 2, 3, 4], [2, 3, 4, 7, 8], [1, 3, 4, 9]) // [3, 4] |
# 数组查找
当对数组进行查找时, indexOf()
用于获取查找项的位置。如果未找到该项,则返回值为 -1
。在 JavaScript 中, 0
被视为 false
,而 大于或小于0
的数字被视为 true
。因此,需要这样来写:
传统写法:
if(arr.indexOf(item) > -1) {} | |
if(arr.indexOf(item) === -1) {} |
简化写法:
if(~arr.indexOf(item)) {} | |
if(!~arr.indexOf(item)) {} |
位非 (~)
运算符对除了 - 1 之外的任何值都返回一个 "真"
值。对其进行取反就是简单地使用 !~
即可。另外,也可以使用 includes () 函数:
if(arr.includes(item)) {} |
# 数组查找最大值索引
但你需要找到一个数组中的最大值的索引
const indexOfMax = (arr) => arr.reduce((prev, curr, i, a) => (curr > a[prev] ? i : prev), 0); | |
indexOfMax([1, 3, 9, 7, 5]); // 2 |
# 数组查找最小值索引
当你需要找到一个数组中的最小值的索引
const indexOfMin = (arr) => arr.reduce((prev, curr, i, a) => (curr < a[prev] ? i : prev), 0) | |
indexOfMin([2, 5, 3, 4, 1, 0, 9]) // 5 |
# 不实用 map 遍历数组
可能每个人数组的 map()
方法,但是可以使用另外一种解决方案来获得相似的效果以及干净的代码。
var friends = [ | |
{ name: 'John', age: 22 }, | |
{ name: 'Peter', age: 23 }, | |
{ name: 'Mark', age: 24 }, | |
{ name: 'Maria', age: 22 }, | |
{ name: 'Monica', age: 21 }, | |
{ name: 'Martha', age: 19 } | |
] | |
var friendsNames = Array.from(friends, ({name}) => name); | |
console.log(friendsNames); // returns ["John", "Peter", "Mark", "Maria", "Monica", "Martha"] |
# 移除数组假值
可以使用 filter()
结合 Boolean
来简化移除数组假值操作。假值指的是在条件判断中被视为 false 的值,例如 null
、 undefined
、空字符串 ("" 或 '')
、 0
、 NaN
和 false
。
传统写法:
let arr = [12, null, 0, 'xyz', null, -25, NaN, '', undefined, 0.5, false]; | |
let filterArray = arr.filter(value => { | |
if(value) { | |
return value | |
}; | |
}); | |
// [12, 'xyz', -25, 0.5] |
简化写法:
let arr = [12, null, 0, 'xyz', null, -25, NaN, '', undefined, 0.5, false]; | |
let filterArray = arr.filter(value => Boolean(value)); // [12, 'xyz', -25, 0.5] |
更简化写法:
let arr = [12, null, 0, 'xyz', null, -25, NaN, '', undefined, 0.5, false]; | |
let filterArray = arr.filter(Boolean); // [12, 'xyz', -25, 0.5] |
Boolean
是 JavaScript 的内置构造函数,通过传递一个值给它,可以将该值转换为布尔值。在这种情况下, Boolean
构造函数作为回调函数传递给 filter()
方法,因此会将每个数组元素转换为布尔值。只有转换结果为真值的元素才会保留在新数组中。
注意:这种方式会将 0 也过滤掉,如果不需要过滤 0,需要进行额外的判断。
# 压缩多个数组
当你需要将多个数组压缩成一个数组
const zip = (...arr) => Array.from({ length: Math.max(...arr.map((a) => a.length)) }, (_, i) => arr.map((a) => a[i])) | |
zip([1,2,3,4], ['a', 'b', 'c', 'd'], ['A', 'B', 'C', 'D']) | |
// [[1, 'a', 'A'], [2, 'b', 'B'], [3, 'c', 'C'], [4, 'd', 'D']] |
# 矩阵交换行和列
当你需要将一个矩阵的行和列进行互相交换
const transpose = (matrix) => matrix[0].map((col, i) => matrix.map((row) => row[i])); | |
transpose( | |
[ // [ | |
[1, 2, 3], // [1, 4, 7], | |
[4, 5, 6], // [2, 5, 8], | |
[7, 8, 9], // [3, 6, 9], | |
] // ] | |
); |
# 找到最接近的数值
当你需要在一个数组中找到一个最接近的值
const closest = (arr, n) => arr.reduce((prev, curr) => (Math.abs(curr - n) < Math.abs(prev - n) ? curr : prev)) | |
closest([29, 87, 8, 78, 97, 20, 75, 33, 24, 17], 50) // 33 |
# 巧用 filter 函数
当 forEach 中含有 if 条件语句时,可以先 filter,然后在 forEach 代替。
// 不好的 | |
function emailClients(clients) { | |
clients.forEach((client) => { | |
const clientRecord = database.lookup(client); | |
if (clientRecord.isActive()) { | |
email(client); | |
} | |
}); | |
} | |
// 好的 | |
function emailClients(clients) { | |
clients | |
.filter(isClientRecord) | |
.forEach(email) | |
} | |
function isClientRecord(client) { | |
const clientRecord = database.lookup(client); | |
return clientRecord.isActive() | |
} |
上面不好的栗子一眼看过去是不是感觉一堆代码在那,一时半会甚至不想去看了。
好的栗子,是不是逻辑很清晰,易读。
- 巧用 filter 函数,把 filter 的回调单开一个函数进行条件处理,返回符合条件的数据
- 符合条件的数据再巧用 forEach,执行 email 函数
# flat
按照一个可指定的深度递归遍历数组:
let nestedArray = [1, 2, [3, 4, [5, 6]]]; | |
let flatArray = nestedArray.flat(); | |
console.log(flatArray); | |
// 输出: [1, 2, 3, 4, [5, 6]] | |
// 指定深度为 2 | |
let deeplyNestedArray = [1, 2, [3, 4, [5, 6]]]; | |
let deeplyFlatArray = deeplyNestedArray.flat(2); | |
console.log(deeplyFlatArray); | |
// 输出: [1, 2, 3, 4, 5, 6] |
使用 Infinity,可展开任意深度的嵌套数组:
var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]]; | |
arr4.flat(Infinity); | |
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] |
# splice
有时候, 在创建代码时有必要替换数组中的特定值, splice()
方法可以很好的完成这种需求。 splice 接收三个参数:
- start:规定添加 / 删除元素的位置
- howmany:要删除的元素数量
- valueToAdd:向数组添加的新元素
var fruits = ['banana', 'apple', 'orange']; | |
fruits.splice(0, 2, 'potato', ''); // 该方法返回删除的元素,['banana', 'apple'] | |
console.log(fruits); // returns ['potato', '', 'orange'] |