# 数组转对象

通用方法

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 的值,例如 nullundefined 、空字符串 ("" 或 '')0NaNfalse

传统写法:

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']