外观
数组
2548字约8分钟
2024-06-12
原生数组方法
总结
- 创建和初始化:
Array.of()
,Array.from()
- 添加和删除:
push()
,pop()
,unshift()
,shift()
,splice()
- 迭代和访问:
forEach()
,map()
,filter()
,reduce()
,find()
,findIndex()
- 合并和切割:
concat()
,slice()
,join()
- 查找元素:
indexOf()
,lastIndexOf()
,includes()
- 其他常用:
reverse()
,sort()
,flat()
,every()
,some()
,fill()
,copyWithin()
,entries()
,keys()
,values()
,at()
创建和初始化数组
Array.of()
: 创建包含所有传入参数的新数组。Array.from()
: 根据类数组对象或可迭代对象创建一个新数组实例。
示例
const array1 = Array.of(1, 2, 3);
console.log(array1); // 输出: [1, 2, 3]
const array2 = Array.from('hello');
console.log(array2); // 输出: ['h', 'e', 'l', 'l', 'o']
添加和删除元素
push()
: 在数组末尾添加一个或多个元素,并返回新的长度。pop()
: 删除数组的最后一个元素,并返回该元素。unshift()
: 在数组开头添加一个或多个元素,并返回新的长度。shift()
: 删除数组的第一个元素,并返回该元素。splice()
: 通过删除或替换现有元素以及/或者添加新元素来修改数组。
示例
const array = [1, 2, 3];
array.push(4);
console.log(array); // 输出: [1, 2, 3, 4]
array.pop();
console.log(array); // 输出: [1, 2, 3]
array.unshift(0);
console.log(array); // 输出: [0, 1, 2, 3]
array.shift();
console.log(array); // 输出: [1, 2, 3]
array.splice(1, 1, 'a');
console.log(array); // 输出: [1, 'a', 3]
迭代和访问元素
forEach()
: 对数组的每个元素执行一次提供的函数。map()
: 创建一个新数组,其结果是该数组中的每个元素调用一个提供的函数后返回的结果。filter()
: 创建一个新数组,其包含通过所提供函数实现的测试的所有元素。reduce()
: 对数组中的每个元素执行一个提供的 reducer 函数(升序执行),将其结果汇总为单个值。find()
: 返回数组中满足提供的测试函数的第一个元素的值。findIndex()
: 返回数组中满足提供的测试函数的第一个元素的索引。
示例
const array = [1, 2, 3, 4];
array.forEach((element) => console.log(element)); // 输出: 1 2 3 4
const mappedArray = array.map((x) => x * 2);
console.log(mappedArray); // 输出: [2, 4, 6, 8]
const filteredArray = array.filter((x) => x > 2);
console.log(filteredArray); // 输出: [3, 4]
const reducedValue = array.reduce((acc, curr) => acc + curr, 0);
console.log(reducedValue); // 输出: 10
const foundElement = array.find((x) => x > 2);
console.log(foundElement); // 输出: 3
const foundIndex = array.findIndex((x) => x > 2);
console.log(foundIndex); // 输出: 2
合并和切割数组
concat()
: 合并两个或多个数组,不修改现有数组,而是返回一个新数组。slice()
: 返回一个新的数组对象,这一对象是一个从开始到结束(不包括结束)选择的原数组的浅拷贝。join()
: 将数组的所有元素连接成一个字符串。
示例
const array1 = [1, 2];
const array2 = [3, 4];
const concatenatedArray = array1.concat(array2);
console.log(concatenatedArray); // 输出: [1, 2, 3, 4]
const slicedArray = array1.slice(1);
console.log(slicedArray); // 输出: [2]
const joinedString = array1.join('-');
console.log(joinedString); // 输出: "1-2"
查找元素
indexOf()
: 返回在数组中可以找到一个给定元素的第一个索引,如果不存在,则返回 -1。lastIndexOf()
: 返回在数组中可以找到一个给定元素的最后一个索引,如果不存在,则返回 -1。includes()
: 判断一个数组是否包含一个指定的值,根据情况返回 true 或 false。
示例
const array = [1, 2, 3, 2];
console.log(array.indexOf(2)); // 输出: 1
console.log(array.lastIndexOf(2)); // 输出: 3
console.log(array.includes(2)); // 输出: true
console.log(array.includes(4)); // 输出: false
其他常用方法
reverse()
: 反转数组中元素的顺序。sort()
: 对数组的元素进行排序并返回数组。flat()
: 按照指定深度递归地将数组展平。
示例
const array = [3, 1, 4, 1, 5, 9];
array.reverse();
console.log(array); // 输出: [9, 5, 1, 4, 1, 3]
array.sort();
console.log(array); // 输出: [1, 1, 3, 4, 5, 9]
const nestedArray = [1, [2, [3, [4]]]];
const flatArray = nestedArray.flat(2);
console.log(flatArray); // 输出: [1, 2, 3, [4]]
at()
返回数组中给定索引处的元素,支持负索引(从数组末尾开始计数)。
const array = [1, 2, 3, 4, 5];
console.log(array.at(0)); // 输出: 1
console.log(array.at(-1)); // 输出: 5
values()
返回一个新的数组迭代器对象,该对象包含数组中每个索引的值。
const array = ['a', 'b', 'c'];
const iterator = array.values();
for (const value of iterator) {
console.log(value); // 输出: 'a', 'b', 'c'
}
fill()
用一个固定值填充数组中从起始索引到终止索引内的全部元素。
const array = [1, 2, 3, 4];
array.fill(0, 1, 3);
console.log(array); // 输出: [1, 0, 0, 4]
some()
测试数组中的某些元素是否至少有一个能通过某个指定函数的测试。它返回一个布尔值。
const array = [1, 2, 3, 4];
const hasEven = array.some(x => x % 2 === 0);
console.log(hasEven); // 输出: true
every()
测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。
const array = [1, 2, 3, 4];
const allEven = array.every(x => x % 2 === 0);
console.log(allEven); // 输出: false
chunk
将数组分成指定大小的块
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const chunked = _.chunk(array, 3);
console.log(chunked);
// 输出: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
原生实现
const chunk = (array, size) =>
array.length === 0 || size <= 0
? []
: Array.from({ length: Math.ceil(array.length / size) }, (v, i) =>
array.slice(i * size, i * size + size)
);
compact
移除数组中的假值 false, null,0, " ", undefined, 和 NaN
import { compact } from 'lodash-es';
const array = [0, 1, false, 2, '', 3, null, NaN, 4, undefined];
const compactedArray = compact(array);
console.log(compactedArray);
// 输出: [1, 2, 3, 4]
原生实现
const array = [0, 1, false, 2, '', 3, null, NaN, 4, undefined];
const compactedArray = array.filter(Boolean);
difference
创建一个新数组,该数组包含第一个数组中不包含在其他数组中的所有值。
_.difference([3, 2, 1], [4, 2]);
// => [3, 1]
_.difference([3, 2, 1, 4, 5], [4, 2]);
// => [3, 1, 5]
原生实现
function difference(array, values) {
return array.filter((element) => !values.includes(element));
}
dropRight
移除数组的后 N 个元素
const array = [1, 2, 3];
const result = _.dropRight(array, 2);
console.log(result);
// 输出: [1]
原生实现
array.slice(0, -2);
head > first
移除数组中的假值 false, null,0, " ", undefined, 和 NaN
const array = [1, 2, 3];
const firstElement = _.head(array);
console.log(firstElement);
// 输出: 1
_.head([]);
// => undefined
原生实现
array[0];
array.at(0);
flattenDeep
用于将多维数组展平为一维数组
import _ from 'lodash-es';
const array = [1, [2, [3, [4]], 5]];
const flatArray = _.flattenDeep(array);
console.log(flatArray); // 输出: [1, 2, 3, 4, 5]
原生实现
function flattenDeep(arr) {
return arr.reduce(
(acc, val) =>
Array.isArray(val) ? acc.concat(flattenDeep(val)) : acc.concat(val),
[]
);
}
array.flat(Infinity);
fromPairs
接收包含键值对的二维数组,并返回一个对象,其中每个键值对数组的第一个元素作为键,第二个元素作为对应的值
const pairs = [
['a', 1],
['b', 2],
['c', 3],
];
const object = _.fromPairs(pairs);
console.log(object); // 输出: { 'a': 1, 'b': 2, 'c': 3 }
原生实现
function fromPairs(pairs) {
const result = {};
pairs.forEach((pair) => {
const [key, value] = pair;
result[key] = value;
});
return result;
}
function fromPairs(pairs) {
return pairs.reduce((acc, [key, value]) => {
acc[key] = value;
return acc;
}, {});
}
toPairs
将一个对象转换为键值对数组
const object = { a: 1, b: 2, c: 3 };
const pairs = _.toPairs(object);
console.log(pairs); // [['a', 1], ['b', 2], ['c', 3]]
原生实现
Object.entries(object);
intersection
返回多个数组的交集
const array1 = [1, 2, 3];
const array2 = [2, 3, 4];
const array3 = [3, 4, 5];
const intersection = _.intersection(array1, array2, array3);
console.log(intersection); // [3]
原生实现
const arrays = [
[1, 2, 3],
[2, 3, 4],
[3, 4, 5],
];
const intersection = arrays.reduce((acc, curr) =>
acc.filter((value) => curr.includes(value))
);
//
const array1 = [1, 2, 3];
const array2 = [2, 3, 4];
const array3 = [3, 4, 5];
const intersection = array1.filter(
(value) => array2.includes(value) && array3.includes(value)
);
intersectionBy
对象数组的交集查找
const array1 = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' },
];
const array2 = [
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' },
{ id: 4, name: 'David' },
];
const intersection = _.intersectionBy(array1, array2, 'id');
console.log(intersection);
// Output: [ { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' } ]
原生实现
const intersection = array1.filter((item1) =>
array2.some((item2) => item1.id === item2.id)
);
intersectionWith
用于根据提供的比较函数计算数组的交集
const array1 = [
{ id: 1, name: 'Alice', age: 25 },
{ id: 2, name: 'Bob', age: 30 },
{ id: 3, name: 'Charlie', age: 35 },
];
const array2 = [
{ id: 2, name: 'Bob', age: 31 },
{ id: 3, name: 'Charlie', age: 35 },
{ id: 4, name: 'David', age: 40 },
];
// 比较函数,根据对象的 id 和 age 是否在一个范围内进行比较
const comparator = (obj1, obj2) =>
obj1.id === obj2.id && Math.abs(obj1.age - obj2.age) <= 1;
const intersection = _.intersectionWith(array1, array2, comparator);
console.log(intersection);
// Output: [ { id: 2, name: 'Bob', age: 30 }, { id: 3, name: 'Charlie', age: 35 } ]
原生实现
const array = [0, 1, false, 2, '', 3, null, NaN, 4, undefined];
const compactedArray = array.filter(Boolean);
console.log(compactedArray);
// 输出: [1, 2, 3, 4]
pull
从数组中移除所有给定值 会改变原数组
without
方法 返回过滤值后的新数组
let array = [1, 2, 3, 4, 5, 1, 2];
_.pull(array, 1, 2);
console.log(array);
// Output: [3, 4, 5]
原生实现
const pull = (array, ...values) => {
return array.filter((element) => !values.includes(element));
};
pullAll
接收一个要移除值的数组
var array = [1, 2, 3, 1, 2, 3];
_.pullAll(array, [2, 3]);
console.log(array);
// => [1, 1]
原生实现
const pull = (array, values) => {
return array.filter((element) => !values.includes(element));
};
pullAllBy
接收一个要移除值的数组
let array = [{ x: 1 }, { x: 2 }, { x: 3 }, { x: 1 }];
_.pullAllBy(array, [{ x: 1 }, { x: 3 }], 'x');
console.log(array);
// Output: [{ 'x': 2 }]
原生实现
const pullAllBy = (array, values, iteratee) => {
const valueSet = new Set(
values.map((value) =>
typeof iteratee === 'function' ? iteratee(value) : value[iteratee]
)
);
return array.filter(
(element) =>
!valueSet.has(
typeof iteratee === 'function' ? iteratee(element) : element[iteratee]
)
);
};
uniq
创建一个去重后的
array
数组副本
_.uniq([2, 1, 2]);
// => [2, 1]
原生实现
//使用 Set 实现 uniq
const uniq = (array) => {
return [...new Set(array)];
};
//使用 filter 和 indexOf 实现 uniq
const uniq = (array) => {
return array.filter((value, index, self) => self.indexOf(value) === index);
};
//使用 reduce 方法实现 uniq
const uniq = (array) => {
return array.reduce((acc, value) => {
if (!acc.includes(value)) {
acc.push(value);
}
return acc;
}, []);
};
//对象数组去重
uniqBy
对象数组去重
let array = [{ x: 1 }, { x: 2 }, { x: 2 }];
let uniqueArray = _.uniqBy(array, 'x');
console.log(uniqueArray);
// Output: [{ 'x': 1 }, { 'x': 2 }]
原生实现
const uniqBy = (array, iteratee) => {
const seen = new Set();
return array.filter((item) => {
const key =
typeof iteratee === 'function' ? iteratee(item) : item[iteratee];
if (!seen.has(key)) {
seen.add(key);
return true;
}
return false;
});
};
const uniqBy = (array, iteratee) => {
const seen = new Set();
return array.reduce((acc, item) => {
const key =
typeof iteratee === 'function' ? iteratee(item) : item[iteratee];
if (!seen.has(key)) {
seen.add(key);
acc.push(item);
}
return acc;
}, []);
};
union
合并多个数组并去除重复值
let array1 = [1, 2, 3];
let array2 = [3, 4, 5];
let array3 = [5, 6, 7];
let unionArray = _.union(array1, array2, array3);
console.log(unionArray);
// Output: [1, 2, 3, 4, 5, 6, 7]
原生实现
//使用 Set 和 spread 操作符
const union = (...arrays) => {
return [...new Set(arrays.flat())];
};
//使用 reduce 和 concat
const union = (...arrays) => {
return arrays.reduce((acc, array) => {
array.forEach((item) => {
if (!acc.includes(item)) {
acc.push(item);
}
});
return acc;
}, []);
};
unionBy
对象数组合并去重
let array1 = [{ x: 1 }, { x: 2 }];
let array2 = [{ x: 2 }, { x: 3 }];
let array3 = [{ x: 1 }, { x: 4 }];
let unionArray = _.unionBy(array1, array2, array3, 'x');
console.log(unionArray);
// Output: [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 4 }]
原生实现
const unionBy = (iteratee, ...arrays) => {
const seen = new Set();
return arrays.flat().reduce((acc, item) => {
const key =
typeof iteratee === 'function' ? iteratee(item) : item[iteratee];
if (!seen.has(key)) {
seen.add(key);
acc.push(item);
}
return acc;
}, []);
};