js 常用数组方法整理,包括常用的数组常用方法、高阶函数 forEach、filter、map。

1、常用数组方法

点击展示代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// 1、删除数组的最后一项  pop()
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.pop();
console.log(fruits); // "Banana", "Orange", "Apple"

var x = fruits.pop(); // Mango

// 2、数组结尾添加一个新元素 push()
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.push("Kiwi"); //"Banana", "Orange", "Apple", "Mango","Kiwi"

var x = fruits.push("Kiwi"); // 5

// 3、删除数组第一个元素 shift()
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.shift(); // "Orange", "Apple", "Mango"

// 4、数组开头返回一个新元素 返回新数组长度 unshift()
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.unshift("Lemon"); //"Lemon" "Banana", "Orange", "Apple", "Mango"

// 5、删除元素 delete 会留下数组未定义的空洞 可以使用pop shift替代
var fruits = ["Banana", "Orange", "Apple", "Mango"];
delete fruits[0]; // empty,"Orange", "Apple", "Mango"

// 6、拼接数组 splice() 第一个参数 2 定义了应添加新元素的位置 第二个参数 定义应删除多少元素 其余参数 定义要添加的新元素 返回一个包含已删除项的数组
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(2, 0, "Lemon", "Kiwi"); // "Banana", "Orange", "Lemon", "Kiwi", "Apple", "Mango"
fruits.splice(2, 2, "Lemon", "Kiwi"); // "Banana", "Orange", "Lemon", "Kiwi",

// 7、删除元素 splice() 在数组中不留“空洞”的情况下移除元素
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.splice(0, 1); //"Orange", "Apple", "Mango"

// 8、合并数组 concat()
var myGirls = ["Cecilie", "Lone"];
var myBoys = ["Emil", "Tobias", "Linus"];
var myChildren = myGirls.concat(myBoys);

// 9、裁剪数组 slice() 源数组不会删除任何元素 第一个参数 开始选取的元素 第二个参数 结束参数为止(不包含)
var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var citrus = fruits.slice(1); // "Orange", "Lemon", "Apple", "Mango"

var fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"];
var citrus = fruits.slice(1, 3); // "Orange", "Lemon" 第2个元素 到 第4个元素 截取结果为第2个和第3个元素

// 10、数组元素结合成字符串 join() 和 toString()
var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.join(","); // Banana,Orange,Apple,Mango
fruits.toString(); // Banana,Orange,Apple,Mango

2、高阶函数

1、forEach

forEach()方法对数组的每个元素执行一次给定的函数。

for example:

1
2
3
4
var array = ["a", "b", "c"];
array.forEach((e) => {
console.log(e); // 'a' 'b' 'c'
});

语法:arr.forEach(callback(currentValue [, index [, array]])[, thisArg])

参数介绍:

callback:为数组中的每个元素执行的函数,该函数接收1~3个参数

currentValue:数组中正在处理的当前元素

index: 数组中正在处理的当前元素的索引

array: forEach()正在操作的数组   数组对象本身

thisArg:可选参数。当执行回调函数callback时,用作this的值。

常见用法:

(1)稀疏数组

不对未初始化的值进行任何操作

1
2
3
4
5
6
7
8
const arratSpace = [1, 3, , 7];
let numCallbackRuns = 0;
arratSpace.forEach(function (e) {
console.log(e);
numCallbackRuns++;
});

console.log("numCallbackRuns:", numCallbackRuns);
(2)for 循环转换成 forEach
1
2
3
4
5
6
7
8
9
10
11
12
const items = ["1", "2", "3", "4"];
const copy = [];

//for循环
for (let i = 0; i < items.length; i++) {
copey.push(items[i]);
}

// forEach
items.forEach(function (itme) {
copy.push(item);
});
(3)thisArg 使用箭头函数 thisArg 参数会被忽略,因为箭头函数绑定了 this 值
(4)对象复制器函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function copy(obj) {
const copy = Object.create(Object.getPrototypeOf(obj));
const propNames = Object.getOwnPropertyNames(obj);

propNames.forEach(function (name) {
const desc = Object.getOwnPropertyDescriptor(obj, name);
Object.defineProperty(copy, name, desc);
});

return copy;
}

const obj1 = { a: 1, b: 2 };

const obj2 = copy(obj1); // obj2看起来和obj1一模一样
(5)数组在迭代时被修改了,则其他元素会被跳过
1
2
3
4
5
6
7
var words = ["one", "two", "three", "four"];
words.forEach(function (word) {
console.log(word);
if (word === "two") {
words.shift();
}
});
(6)promise 或 async 函数的使用
1
2
3
4
5
6
7
8
9
10
11
12
13
let ratings = [5, 4, 5];

let sum = 0;

let sumFunction = async function (a, b) {
return a + b;
};

ratings.forEach(async function (rating) {
sum = await sumFunction(sum, rating);
});

console.log(sum); // 0

2、filter

filter()创建一个新数组,其包含通过所提供函数实现的测试的所有元素。 返回满足条件的新数组,不满足则返回空数组。

for example

1
2
3
4
5
6
const words = ["111", "222", "333333", "4444444", "55555555"];
const result = words.filter((word) => {
word.length > 5;
});

console.log(result); // 333333 4444444 55555555

语法:var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])

参数:
callback:用来测试数组的每个元素的函数。返回 true 表示该元素通过测试,保留该元素,false 则不保留。

element:数组中当前正在处理的元素

index:正在处理的元素在数组中的索引

array:调用filter的数组本身

thisArg:执行callback时,用于this的值

返回值:

一个新的、由通过测试的元素组成的数组,如果没有任何数组元素通过测试,则返回空数组。

用法:

(1)筛选排除所有较小的值

1
2
3
4
5
function isBig(e) {
return e >= 10;
}
var filterd = [3, 6, 9, 14, 32].filter(isBig);
// [14,32]

(2)过滤 JSON 中的无效条目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var arr = [
{ id: 12 },
{ id: -1 },
{ id: 0 },
{ id: 3 },
{ id: 14.4 },
{},
{ id: null },
{ id: NaN },
{ id: "undefined" },
];
var entries = 0;
function isNumber(obj) {
return obj !== undefined && typeof obj === "number" && !isNaN(obj);
}
function filterID(item) {
if (isNumber(item.id) && item.id !== 0) {
return true;
}
entries++;
return false;
}
var arrId = arr.filter(filterID);
console.log(arrId); // [{id:12},{id:-1},{id:3},{id:14.4}]
console.log(entries); // 5

(3)在数组中搜索:根据搜索条件来过滤数组内容

1
2
3
4
5
6
7
8
9
var fruits ['apple','banana','grapes','mango','orange']
function filterItems(query){
return fruits.filter(function(e){
return e.toLowerCase().indexOf(query.toLowerCase()) > -1
})
}

console.log(filterItem('ap')) // ['apple','grapes']
console.log(filterItem('an')) // ['banana','mango','orange']

上面是 es5 的写法,下面是 es6 的写法

1
2
3
4
5
6
7
8
var fruits ['apple','banana','grapes','mango','orange']
const filterItems = (query) =>{
return fruits.filter((e) =>
e.toLowerCase().indexOf(query,toLowerCase()) > -1
)
}
console.log(filterItem('ap')) // ['apple','grapes']
console.log(filterItem('an')) // ['banana','mango','orange']

3、map

map()方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。 原数组不会改变

1
2
3
const array = [1, 2, 3, 4];
const maps = array.map((x) => x * 2);
console.log(maps); // 2 4 6 8

用法:

(1)格式化数组中的对象

1
2
3
4
5
6
7
8
9
10
11
12
var array = [
{ key: 1, value: 10 },
{ key: 2, value: 20 },
{ key: 3, value: 30 },
];

var formatterArray = array.map(function (obj) {
var o = {};
o[obj.key] = obj.value;
return o;
});
console.log(formatterArray); // [{1:10},{2:20},{3:30}]

(2)使用包含一个参数的函数来构建一个数字数组

1
2
3
4
5
var numbers = [1, 4, 9];
var double = numbers.map(function (item) {
return item * 2;
});
console.log(double); // [2,8,18]

includes比indexOf好在哪里?

includes可以检测NaN,indexOf不能,includes内部使用了Number.isNaN对NaN进行了匹配