js 中数组的方法种类众多,有 ES5 之前版本中存在的,ES5 新增,ES6 新增等;并且数组的方法还有原型方法和从 Object 继承的方法,这里只介绍数组在每个版本中原型上的方法。
编号 | 方法名 | 对应版本 | 功能 | 原数组是否改变 |
---|---|---|---|---|
1 | concat(data1, data2, ...) | ES5 | 合并数组,并返回合并之后的数据 | n |
2 | join(str) | ES5 | 使用分隔符,将数组转为字符串并返回 | n |
3 | pop() | ES5 | 删除最后一位,并返回删除的数据 | y |
4 | shift() | ES5 | 删除第一位,并返回删除的数据 | y |
5 | unshift(newData1, newData2, ...) | ES5 | 在第一位新增一或多个数据,返回新增后的数组长度 | y |
6 | push(newData1, newData2, ...) | ES5 | 在最后一位新增一或多个数据,返回新增后的数组长度 | y |
7 | reverse() | ES5 | 反转数组,返回结果 | y |
8 | slice(start, end) | ES5 | 截取指定位置的数组,并返回 | n |
9 | sort(callback) | ES5 | 排序(字符规则),返回结果 | y |
10 | splice(start, num, data1, data2, ...) | ES5 | 删除指定位置,并替换,返回删除的数据 | y |
11 | toString() | ES5 | 直接转为字符串,并返回 | n |
12 | valueOf() | ES5 | 返回数组对象的原始值 | n |
13 | indexOf(value, start) | ES5 | 查询并返回数据的索引 | n |
14 | lastIndexOf(value, start) | ES5 | 反向查询并返回数据的索引 | n |
15 | forEach(callback) | ES5 | 参数为回调函数,会遍历数组所有的项,回调函数接受三个参数 | n |
16 | map(callback) | ES5 | 同 forEach,同时回调函数返回数据,组成新数组由 map 返回 | n |
17 | filter(callback) | ES5 | 同 forEach,同时回调函数返回布尔值,为 true 的数据组成新数组由 filter 返回 | n |
18 | every(callback) | ES5 | 同 forEach,同时回调函数返回布尔值,全部为true,则every返回 true,否则返回 false | n |
19 | some(callback) | ES5 | 同 forEach,同时回调函数返回布尔值,只要有一个为 true,则 some 返回 true,否则返回 false | n |
20 | reduce(callback, initial) | ES5 | 归并,同forEach,迭代数组的所有项,并构建一个最终值,由reduce 返回 | n |
21 | reduceRight(callback, initial) | ES5 | 反向归并,同forEach,迭代数组的所有项,并构建一个最终值,由reduceRight 返回 | n |
22 | find(callback) | ES6 | 寻找并返回数组中符合条件的第一个元素的值 | n |
23 | findIndex(callback) | ES6 | 寻找并返回数组中符合条件的第一个元素的索引 | n |
24 | includes(item, index) | ES6 | 判断一个数组是否包含一个指定的值,返回 true 或 false | n |
25 | Array.from(likeObj) | ES6 | 将类似数组的对象和可遍历对象转为真正的数组,并返回 | n |
26 | Array.of(value1, value2, …) | ES6 | 将一组值转变为数组,并返回 | n |
27 | fill(value, start, end) | ES6 | 用一个固定值填充一个数组,返回结果 | y |
28 | copyWithin(index, start, end) | ES6 | 从数组的指定位置拷贝元素到数组的另一个指定位置,返回结果 | n |
功能:用于连接两个或多个数组,该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。
参数:
var arr1 = [1,2,3]
var arr2 = arr1.concat();
console.log(arr1); // [1,2,3]---原数组
console.log(arr1 === arr2); // false
console.log(arr2); // [1,2,3]---原数组的副本
console.log(arr1.concat("hello","world")); // [1,2,3,"hello","world"]
console.log(arr1.concat(["a","b"],[[3,4],{"name":"admin"}])); // [1,2,3,"a","b",[3,4],{"name":"admin"}]
console.log(arr1); // [1,2,3]---原数组未改变
功能:根据指定分隔符将数组中的所有元素放入一个字符串,并返回这个字符串。该方法
参数: 功能:方法用于删除并返回数组的最后一个元素。 参数:无。 功能:方法用于删除并返回数组的第一个元素
var arr = [1,2,3];
console.log(arr.join()); // "1,2,3"
console.log(arr.join("-")); // "1-2-3"
console.log(arr); // [1,2,3]---原数组未改变
3. pop()
var arr = [1,2,3];
console.log(arr.pop()); // 3
console.log(arr); // [1,2]
4. shift()
参数:无。
var arr = [1,2,3]
console.log(arr.shift()); // 1
console.log(arr); // [2,3]---原数组改变
功能:向数组的开头添加一个或更多元素,并返回新的数组长度。
参数:
var arr = [1,2,3];
console.log(arr.unshift("hello")); // 4
console.log(arr); // ["hello",1,2,3]---原数组改变
console.log(arr.unshift("a","b")); // 6
console.log(arr); // ["a","b","hello",1,2,3]---原数组改变
功能:向数组的末尾添加一个或更多元素,并返回新的数组长度。
参数:
var arr = [1,2,3];
console.log(arr.push("hello")); // 4
console.log(arr); // [1,2,3,"hello"]---原数组改变
console.log(arr.push("a","b")); // 6
console.log(arr); // [1,2,3,"hello","a","b"]---原数组改变
功能:反转数组中元素的顺序。
参数:无。
var arr = [1,2,3];
console.log(arr.reverse()); // [3,2,1]
console.log(arr); // [3,2,1]---原数组改变
功能:可从已有的数组中返回选定的元素。
参数:
start 和end 都可以为负数,负数时表示从后往前数,如 -1 表示最后一位。
var arr = ["Tom","Jack","Lucy","Lily","May"];
console.log(arr.slice(1,3)); // ["Jack","Lucy"]
console.log(arr.slice(1)); // ["Jack","Lucy","Lily","May"]
console.log(arr.slice(-4,-1)); // ["Jack","Lucy","Lily"]
console.log(arr.slice(-2)); // ["Lily","May"]
console.log(arr.slice(1,-2)); // ["Jack","Lucy"]
console.log(arr); // ["Tom","Jack","Lucy","Lily","May"]---原数组未改变
功能:对数组中的元素进行排序,默认是升序。
var arr = [6,1,5,2,3];
console.log(arr.sort()); // [1, 2, 3, 5, 6]
console.log(arr); // [1, 2, 3, 5, 6]---原数组改变
但是在排序前,会先调用数组的 toString 方法,将每个元素都转成字符串之后,再进行排序,此时会按照字典排序,逐位比较,进行排序。
var arr = [6,1024,52,256,369];
console.log(arr.sort()); // [1024, 256, 369, 52, 6]---字典顺序排序
console.log(arr); //[1024, 256, 369, 52, 6]---原数组改变
参数:
var arr = [6,1024,52,256,369];
console.log(arr.sort(fn)); // [6, 52, 256, 369, 1024]---数值排序
console.log(arr); // [6, 52, 256, 369, 1024]---原数组改变
function fn(a,b){
return a - b;
}
功能:向数组中添加,或从数组删除,或替换数组中的元素,然后返回被删除/替换的元素。
参数::
(1) 不传参时:无操作。
var arr = ["Tom","Jack","Lucy","Lily","May"];
console.log(arr.splice()); // []
console.log(arr); // ["Tom","Jack","Lucy","Lily","May"]---无操作
(2) 只传入 start:表示删除索引为 start 及 start 之后的所有元素。
var arr = ["Tom","Jack","Lucy","Lily","May"];
console.log(arr.splice(2)); // ["Lucy", "Lily", "May"]---从索引2开始删除后面的所有元素
console.log(arr); // ["Tom", "Jack"]---原数组改变
(3) 传入 start 和 num:表示从索引为 start 的数据开始删除,删除 num 个。
var arr = ["Tom","Jack","Lucy","Lily","May"];
console.log(arr.splice(2,2)); // ["Lucy", "Lily"]---从索引2开始删除2个元素
console.log(arr); // ["Tom", "Jack", "May"]---原数组改变
(4) 传入更多:表示从索引为 start 的数据开始删除,删除 num 个,并将第3个参数及后面所有参数,插入到 start 的位置。
var arr = ["Tom","Jack","Lucy","Lily","May"];
console.log(arr.splice(2,2,"a","b")); // ["Lucy", "Lily"]---从索引2开始删除2个元素,并将"a"和"b"插入到索引2的位置
console.log(arr); // ["Tom", "Jack", "a", "b", "May"]---原数组改变
(5) 添加案例:传入 start、0(num)和多个参数(要添加的值),表示将第3个参数及后面所有参数,插入到 start 的位置。
var arr = ["Tom","Jack","Lucy","Lily","May"];
console.log(arr.splice(2,0,"a","b")); // []
console.log(arr); // ["Tom", "Jack", "a", "b", "Lucy", "Lily", "May"]---原数组改变
(6) 替换案例:传入index(即start)、1(num)和 value(修改后的值),表示修改索引为 index 的元素为 value。
var arr = [1, 2, 3, 4, 5, 6];
console.log(arr.splice(2, 1, 7)); // [3]---将索引2的元素替换为7
console.log(arr); // [1, 2, 7, 4, 5, 6]---原数组改变
功能:转换成字符串,类似于没有参数的 join。该方法会在数据发生隐式类型转换时被自动调用,如果手动调用,就是直接转为字符串。
参数:无。
var arr = [1,2,3];
console.log(arr.toString()); // 1,2,3
console.log(arr); // [1,2,3]---原数组未改变
功能:返回数组的原始值(一般情况下其实就是数组自身),一般由 js 在后台调用,并不显式的出现在代码中。
参数:无。
var arr = [1,2,3];
console.log(arr.valueOf()); // [1,2,3]
console.log(arr); // [1,2,3]
//为了证明返回的是数组自身
console.log(arr.valueOf() == arr); // true
功能:根据指定的数据,从左向右,查询在数组中出现的位置,如果不存在指定的数据,返回 -1。该方法是查询方法,不会对现有的数组产生改变。
参数:
var arr = ["h","e","l","l","o"];
console.log(arr.indexOf("l")); // 2
console.log(arr.indexOf("l",3)); // 3
console.log(arr.indexOf("l",4)); // -1
console.log(arr.indexOf("l",-1)); // -1
console.log(arr.indexOf("l",-3)); // 2
功能:同 indexOf,查询顺序是从右到左。
参数:同 indexOf。
var arr = ["h","e","l","l","o"];
console.log(arr.lastIndexOf("l")); // 3
console.log(arr.lastIndexOf("l",3)); // 3
console.log(arr.lastIndexOf("l",1)); // -1
console.log(arr.lastIndexOf("l",-3)); // 2
console.log(arr.lastIndexOf("l",-4)); // -1
功能:用来遍历数组,该方法没有返回值。forEach 接收的回调函数会根据数组的每一项执行。
参数:
var arr = ["Tom","Jack","Lucy","Lily","May"];
var a = arr.forEach(function (value,index,self) {
console.log(value + "--" + index + "--" + (arr === self));
});
// 打印结果为:
// Tom--0--true
// Jack--1--true
// Lucy--2--true
// Lily--3--true
// May--4--true
console.log(a); // undefined---forEach没有返回值
// 该方法为遍历方法,不会修改原数组
功能:
(1) 同forEach功能;
(2) map的回调函数会将执行结果返回,最后 map 将所有回调函数的返回值组成新数组返回。
参数:
// 功能1:同forEach
var arr = ["Tom","Jack","Lucy","Lily","May"];
var a = arr.map(function (value,index,self) {
console.log(value + "--" + index + "--" + (arr === self))
});
// 打印结果为:
// Tom--0--true
// Jack--1--true
// Lucy--2--true
// Lily--3--true
// May--4--true
// 功能2:每次回调函数的返回值被map组成新数组返回
var arr = ["Tom","Jack","Lucy","Lily","May"];
var a = arr.map(function(value,index,self){
return "hi:"+value;
});
console.log(a); // ["hi:Tom", "hi:Jack", "hi:Lucy", "hi:Lily", "hi:May"]
console.log(arr); // ["Tom", "Jack", "Lucy", "Lily", "May"]---原数组未改变
功能:
(1) 同 forEach 功能;
(2) filter 的回调函数需要返回布尔值,遍历所有,最后 filter 将所有回调函数的返回值为 true 的元素组成新数组返回(此功能可理解为“过滤”)。
参数:
// 功能1:同forEach
var arr = ["Tom","Jack","Lucy","Lily","May"];
var a = arr.filter(function (value,index,self) {
console.log(value + "--" + index + "--" + (arr === self));
});
// 打印结果为:
// Tom--0--true
// Jack--1--true
// Lucy--2--true
// Lily--3--true
// May--4--true
// 功能2:当回调函数的返回值为true时,本次的数组值返回给filter,被filter组成新数组返回
var arr = ["Tom","Jack","Lucy","Lily","May"];
var a = arr.filter(function (value,index,self) {
return value.length > 3;
});
console.log(a); // ["Jack", "Lucy", "Lily"]
console.log(arr); // ["Tom", "Jack", "Lucy", "Lily", "May"]---原数组未改变
功能:判断数组中每一项是否都满足条件,只有所有项都满足条件,才会返回 true,否则返回 false。
参数:
功能1:当回调函数的返回值为 true 时,类似于 forEach 的功能,遍历所有;如果为 false,那么停止执行,后面的数据不再遍历,停在第一个返回 false 的位置。
// demo1:
var arr = ["Tom","abc","Jack","Lucy","Lily","May"];
var a = arr.every(function (value,index,self) {
console.log(value + "--" + index + "--" + (arr == self))
});
// 打印结果为:
// Tom--0--true
//因为回调函数中没有return true,默认返回undefined,等同于返回false
// demo2:
var arr = ["Tom","abc","Jack","Lucy","Lily","May"];
var a = arr.every(function (value,index,self) {
console.log(value + "--" + index + "--" + (arr == self))
return value.length < 4;
});
// 打印结果为:
// Tom--0--true
// abc--1--true
// Jack--2--true
//因为当遍历到Jack时,回调函数到return返回false,此时Jack已经遍历,但是后面数据就不再被遍历了
// demo3:
var arr = ["Tom","abc","Jack","Lucy","Lily","May"];
var a = arr.every(function(value,index,self){
console.log(value + "--" + index + "--" + (arr == self))
return true;
});
// 打印结果为:
// Tom--0--true
// abc--1--true
// Jack--2--true
// Lucy--3--true
// Lily--4--true
// May--5--true
//因为每个回调函数的返回值都是 true,那么会遍历数组所有数据,等同于 forEach 功能
功能2:使用 every 的返回值。当每个回调函数的返回值都为 true 时,every 的返回值为 true,只要有一个回调函数的返回值为 false,every 的返回值就是 false。
// demo1:
var arr = ["Tom","abc","Jack","Lucy","Lily","May"];
var a = arr.every(function(value,index,self){
return value.length > 3;
});
console.log(a); //false
//demo2:
var arr = ["Tom","abc","Jack","Lucy","Lily","May"];
var a = arr.every(function(value,index,self){
return value.length > 2;
});
console.log(a); //true
功能:判断数组中是否存在满足条件的项,只要有一项满足条件,就会返回true,否则返回 false。
参数:
功能1:使用 some 遍历数组元素。因为要判断数组中的每一项,只要有一个回调函数返回 true,some 都会返回 true,所以与 every 正好相反,当遇到一个回调函数的返回值为 true 时,可以确定结果,那么停止执行,后面的数据不再遍历,停在第一个返回 true 的位置;当回调函数的返回值为 false 时,需要继续向后执行,到最后才能确定结果,所以会遍历所有数据,实现类似于 forEach 的功能,遍历所有。
// demo1:
var arr = ["Tom","abc","Jack","Lucy","Lily","May"];
var a = arr.some(function (value, index, self) {
console.log(value + "--" + index + "--" + (arr === self))
return value.length > 3;
});
// 打印结果为:
// Tom--0--true
// abc--1--true
// Jack--2--true
// demo2:
var arr = ["Tom","abc","Jack","Lucy","Lily","May"];
var a = arr.some(function (value ,index ,self) {
console.log(value + "--" + index + "--" + (arr === self))
return true;
});
// 打印结果为:
// Tom--0--true
// demo3:
var arr = ["Tom","abc","Jack","Lucy","Lily","May"];
var a = arr.some(function (value, index, self){
console.log(value + "--" + index + "--" + (arr === self))
return false;
});
// 打印结果为:
// Tom--0--true
// abc--1--true
// Jack--2--true
// Lucy--3--true
// Lily--4--true
// May--5--true
功能2:使用 some 的返回值。与 every 相反,只要有一个回调函数的返回值为 true,some 的返回值就为 true,所有回调函数的返回值都为 false,some 的返回值才为 false。
// demo1:
var arr = ["Tom","abc","Jack","Lucy","Lily","May"];
var a = arr.some(function (value,index,self) {
return value.length > 3;
});
console.log(a); // true
// demo2:
var arr = ["Tom","abc","Jack","Lucy","Lily","May"];
var a = arr.some(function (value,index,self) {
return value.length > 4;
})
console.log(a); // false
功能:从数组的第1项开始,逐个遍历到最后,迭代数组的所有元素,然后构建一个最终返回的值。
reduce 接收一个或两个参数:第一个是回调函数(callback),表示在数组的每一项上调用的函数;第二个参数(可选的)作为归并的初始值(initial),被回调函数第一次执行时的第一个参数接收。
参数:
callback,必须,默认有四个参数,分别为 pre(上次回调的返回值),item(遍历到的数组的元素),index(对应的索引),self(数组自身)。callback 返回的任何值都会作为下一次执行的 pre。
initial,可选。如果 initial 参数被省略,那么第1次迭代就发生在数组的第2项上,即第1次callback的 pre 参数是数组的第1项,item 参数就是数组的第2项。
// demo1: 不省略 initial 参数,回调函数没有返回值
var arr = [10,20,30,40,50];
arr.reduce(function (pre, item, index, self) {
console.log(pre + "--" + item + "--" + index + "--" + (arr === self))
}, 2023);
// 打印结果为:
// 2023--10--0--true
// undefined--20--1--true
// undefined--30--2--true
// undefined--40--3--true
// undefined--50--4--true
// 此时回调函数没有 return,所以从第二次开始,pre 拿到的是 undefined
// demo2: 省略 initial 参数,回调函数没有返回值
var arr = [10,20,30,40,50];
arr.reduce(function (pre , item, index, self) {
console.log(pre + "--" + item + "--" + index + "--" + (arr === self))
});
// 打印结果为:第一次,回调函数的第一个参数是数组的第一项。第二个参数就是数组的第二项
// 10--20--1--true
// undefined--30--2--true
// undefined--40--3--true
// undefined--50--4--true
// 此时回调函数没有return,所以从第二次开始,prev拿到的是undefined
// demo3: 不省略 initial 参数,回调函数有返回值
var arr = [10,20,30,40,50];
arr.reduce(function(pre, item, index, self) {
console.log(pre + "--" + item + "--" + index + "--" + (arr == self));
return "hello";
}, 2023);
// 打印结果为:
// 2023--10--0--true
// hello--20--1--true
// hello--30--2--true
// hello--40--3--true
// hello--50--4--true
// 此时回调函数有return,所以从第二次开始,pre拿到的是回调函数return的值
// demo4: 省略 initial 参数,回调函数有返回值
var arr = [10,20,30,40,50];
arr.reduce(function (pre, item, index, self) {
console.log(pre + "--" + item + "--" + index + "--" + (arr == self));
return "hello";
});
// 打印结果为:第一次,回调函数的第一个参数是数组的第一项。第二个参数就是数组的第二项
// 10--20--1--true
// hello--30--2--true
// hello--40--3--true
// hello--50--4--true
// 此时回调函数有return,所以从第二次开始,prev拿到的是回调函数return的值
// demo5:使用 reduce 计算数组中所有数据的和
var arr = [10,20,30,40,50];
var sum = arr.reduce((pre, item) => pre + item);
console.log(sum); //150
// 回调函数的最后一次return的结果被返回到reduce方法的身上
// demo6:使用 reduce 计算数组中所有数据的和
var arr = [10,20,30,40,50];
var sum = arr.reduce((pre, item) => pre + item, 8);
console.log(sum); //158
// 回调函数的最后一次 return 的结果被返回到 reduce 方法的身上
// 因为reduce有第二个参数initial,在第一次执行时被计算,所以最终结果被加上 8
功能:与 reduce 类似,从数组的最后一项开始,向前逐个遍历到第1项,迭代数组的所有元素,然后构建一个最终返回的值。
参数:同 reduce。
//对象数组obj按照给定key去重(重复元素保留后出现的)
function unique(obj, key) {
let index = -1;
let arr = obj.reduceRight((pre, item) => {
if (pre.map((item) => item[key]).includes(item[key])) {
return pre;
} else {
return [...pre, item];
}
}, []);
return arr.reverse();
}
const users = [
{ name: "ddd", age: 18 },
{ name: "aaa", age: 12 },
{ name: "bbb", age: 13 },
{ name: "ccc", age: 15 },
{ name: "ddd", age: 14 },
{ name: "ccc", age: 17 },
{ name: "aaa", age: 16 },
];
console.log(unique(users, "name"));
//输出结果:
// [
// { name: "bbb", age: 13 },
// { name: "ddd", age: 14 },
// { name: "ccc", age: 17 },
// { name: "aaa", age: 16 },
// ]
功能:返回满足条件的数组的第一个元素。当数组中的元素在测试函数中返回 true 时,返回符合条件的第一个元素,之后不再调用测试函数判断剩下的元素,如果每个元素都执行了测试函数,没有符合的元素,则返回 undefined。该方法不会改变现有的数组。
参数:
const arr = [1, 2, 3, 4];
const findItem = arr.find((item) => {
return item < 2;
});
const findItem1 = arr.find((item) => {
return item > 5;
});
console.log(findItem); // 1
console.log(findItem1); // undefined
功能:返回满足条件的数组的第一个元素的索引值。当数组中的元素在测试函数中返回 true 时,返回符合条件的第一个元素的索引值,之后不再调用测试函数判断剩下的元素,如果每个元素都执行了测试函数,没有符合的元素,则返回 -1 。该方法不会改变现有的数组。
参数:
const arr = [1, 2, 3, 4];
const findItem = arr.findIndex((item) => {
return item > 2;
});
const findItem1 = arr.findIndex((item) => {
return item < 5;
});
console.log(findItem); // 2
console.log(findItem1); // -1
功能:用来判断一个数组是否包含一个指定的值,如果是则返回 true,否则返回 false。该方法不会改变现有的数组。
参数:
const arr = ["a","b","c","d"];
const result1 = arr.includes("b");
const result2 = arr.includes("b",2);
const result3 = arr.includes("b",-1);
const result4 = arr.includes("b",-3);
console.log(result1); // true
console.log(result2); // false
console.log(result3); // flase
console.log(result4); // true
功能:用于将类似数组的对象(即有length属性的对象)和可遍历对象转为真正的数组。该方法不会改变现有的数组。
参数:
const json ={
'0': '喜',
'1': '欢',
'2': '你',
length: 3
};
const arr = Array.from(json);
console.log(arr); // ["喜", "欢", "你"]
功能:将一组值转变为数组。参数不分类型,只分数量,数量为 0 返回空数组。该方法不会改变现有的数组。
参数:
let arr1 = Array.of(1,2,3);
let arr2 = Array.of([1,2,3]);
let arr3 = Array.of(undefined);
let arr4 = Array.of();
console.log(arr1); // [1, 2, 3]
console.log(arr2); // [[1, 2, 3]]
console.log(arr3); // [undefined]
console.log(arr4); // []
功能:用一个固定值填充一个数组中从起始索引到
参数: 功能:用于从数组的指定位置拷贝元素到数组的另一个指定位置中,会覆盖原有成员。该方法不会改变现有的数组。 参数:
let arr = [1,2,3,4,5,6];
arr.fill(0); // [0, 0, 0, 0, 0, 0]
arr.fill(0,1); // [1, 0, 0, 0, 0, 0]
arr.fill(0,1,2); // [1, 0, 3, 4, 5, 6]
arr.fill(0,-1); // [1, 2, 3, 4, 5, 0]
arr.fill(0,1,-1); // [1, 0, 0, 0, 0, 6]
28. copyWithin(index, start, end)
const arr = [1,2,3,4,5,6];
const result1 = [1,2,3,4,5,6].copyWithin(0);
const result2 = [1,2,3,4,5,6].copyWithin(0,1);
const result3 = [1,2,3,4,5,6].copyWithin(1,3,5);
const result4 = [1,2,3,4,5,6].copyWithin(1,2,-1);
const result5 = [1,2,3,4,5,6].copyWithin(1,-4,6);
console.log(result1); // [1, 2, 3, 4, 5, 6]
console.log(result2); // [2, 3, 4, 5, 6, 6]
console.log(result3); // [1, 4, 5, 4, 5, 6]
console.log(result4); // [1, 3, 4, 5, 5, 6]
console.log(result5); // [1, 3, 4, 5, 6, 6]