Array

115 阅读14分钟

复制和填充方法

arr.copyWithin(target,[start,end])

浅复制 在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,使用这个方法,会修改当前数组。 参数: target(必需):从该位置开始替换数据。如果为负值,表示倒数。 start(可选):从该位置开始读取数据,默认为 0。如果为负值,表示从末尾开始计算。 end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算。

Array.prototype.copyWithin()
let arr = ['上海','重庆','北京','广东']
let arr2 = arr.copyWithin(0,2,3)
console.log(arr) //[ '北京', '重庆', '北京', '广东' ]
console.log(arr2) //[ '北京', '重庆', '北京', '广东' ]

arr.fill(value, start, end)

用于将一个固定值替换数组的元素 fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。

['a', 'b', 'c'].fill(7)

let arr = ['上海','重庆','北京','广东']
let arr2 = arr.fill('四川',0,1)
console.log(arr2) //[ '四川', '重庆', '北京', '广东' ]

转换方法

toString()

返回由数组中每个值的等效字符串拼接而成的一个逗号分隔的字符串。

let colors = ["red", "blue", "green"];
console.log(colors.toString()) //red,blue,green

arr.join([separator])

用于把数组中的所有元素转换一个字符串,元素是通过指定的分隔符进行分隔的

let colors = ["red", "green", "blue"];
console.log(colors.join(",")); // red,green,blue
console.log(colors.join("||")); // red||green||blue

栈方法

arr.push(item1, item2, ..., itemX)

将一个或多个元素添加到数组的末尾,并返回新数组的长度

let arr= ['red']
let arr1 = arr.push('blue')
console.log(arr) //["red", "blue"]
console.log(arr1) //2

arr.pop()

删除数组的最后一个元素并返回删除的元素

let arr = ["red", "blue","black"]
let arr1 = arr.pop()
console.log(arr) //["red", "blue"]
console.log(arr1) //black

队列方法

push()

arr.shift()

删除并返回数组的第一个元素

let arr = ["red", "blue","black"]
let arr1 = arr.shift()
console.log(arr) //["blue","black"]
console.log(arr1) //red

排序方法

arr.reverse()

反转数组的元素顺序

let values = [1, 2, 3, 4, 5];
values.reverse();
alert(values); // 5,4,3,2,1

arr.sort()

数组排序

arr.sort((a, b) => a - b)  

操作方法

arr.concat(a2,a3,...aX)

方法用于连接两个或多个数组,返回新数组

let colors = ["red", "green", "blue"];
let colors2 = colors.concat("yellow", ["black", "brown"]);
console.log(colors); // ["red", "green","blue"]
console.log(colors2); // ["red", "green", "blue", "yellow", "black", "brown"]

arr.slice(start, end)

截取数组的某一部分,返回新数组

let colors = ["red", "green", "blue", "yellow", "purple"];
let colors2 = colors.slice(1);
let colors3 = colors.slice(1, 4);
alert(colors2); // green,blue,yellow,purple
alert(colors3); // green,blue,yellow

注意:如果 slice() 的参数有负值,那么就以数值长度加上这个负值的结果确定位置。比 如,在包含 5 个元素的数组上调用 slice(-2,-1) ,就相当于调用 slice(3,4) 。如果结 束位置小于开始位置,则返回空数组。

arr.splice(index,howmany,item1,.....,itemX)

用于插入、删除或替换数组的元素

删除: 需要给 splice() 传 2 个参数:要删除的第一个元素的位置和要删除的元素数量。可以从数组中删除任意多个元素,比如 splice(0, 2) 会删除前两个元素

插入: 需要给 splice() 传 3 个参数:开始位置、0(要删除的元素数量)和要插入的元素,可以在数组中指定的位置插入元素。第三个参数之后还可以传第四个、第五个参数,乃至任意多个要插入的元素。比如,splice(2, 0, "red", "green") 会从数组位置 2 开始插入字符串"red" 和 "green" 。

替换: splice() 在删除元素的同时可以在指定位置插入新元素,同样要传入 3 个参数:开始位置、要删除元素的数量和要插入的任意多个元素。要插入的元素数量不一定跟删除的元素数量一致。比如, splice(2, 1, "red", "green") 会在位置 2 删除一个元素,然后从该位置开始向数组中插入 "red" 和 "green" 。

let colors = ["red", "green", "blue"];
let removed = colors.splice(0,1); // 删除第一项
alert(colors); // green,blue
alert(removed); // red,只有一个元素的数组
removed = colors.splice(1, 0, "yellow", "orange"); // 在位置 1 插入两个元素
alert(colors); // green,yellow,orange,blue
alert(removed); // 空数组
removed = colors.splice(1, 1, "red", "purple"); // 插入两个值,删除一个元素
alert(colors); // green,red,purple,orange,blue
alert(removed); // yellow,只有一个元素的数组

搜索和位置方法

arr.indexOf(item,start)

返回数组中某个指定的元素中首次出现的位置, 返回-1未找到

let arr = ['重庆','北京','天津','上海','四川','北京','北京','重庆']

let index = arr.indexOf('北京')

console.log(index); //1
console.log(arr[index]);//北京

let i = arr.indexOf('北京',3)
console.log(i);//5

arr.lastIndexOf(item,start)

返回一个指定的字符串值最后出现的位置,存在第二个参数向前查找

let arr = ['重庆','北京','天津','上海','四川','北京','北京','重庆']

let index = arr.lastIndexOf('北京')

console.log(index); //6 从右往左第一个出现的位置
console.log(arr[index]);//北京

let i = arr.lastIndexOf('北京',3)
console.log(i);//1 从索引3开始往左出现的第一个位置

arr.includes(searchElement, fromIndex)

判断一个数组是否包含一个指定的值,返回boolean 该方法的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置

let arr = ['上海','重庆','北京','广东']

let bool = arr.includes('重庆')
console.log(bool) //true


let arr = ['上海','重庆','北京','广东']

let bool = arr.includes('重庆',2)
console.log(bool) //false

断言函数

arr.find(function(currentValue, index, arr),thisValue)

用于找出第一个符合条件的数组成员. 返回第一个匹配的元素

let arr = ['上海','重庆','北京','广东']
let arr2 = arr.copyWithin(0,2,3)
let arr3 = arr2.find((n)=>n==='北京')
console.log(arr2) //[ '北京', '重庆', '北京', '广东' ]
console.log(arr3) //北京

//find()和findIndex()的第二个参数不能是箭头函数
let arr = ['上海','重庆','北京','广东']
let arr2 = arr.copyWithin(0,2,3)
let person = {name: '广东', age: 20};
let arr3 = arr2.find(function (n) {
  return n === this.name
},person)

console.log(arr3) //广东

arr.findIndex(function(currentValue, index, arr),thisValue)

返回第一个匹配元素的索引 返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1

let arr = ['上海','重庆','北京','广东']
let arr2 = arr.copyWithin(0,2,3)
let arr3 = arr2.findIndex((n)=>n==='重庆')
console.log(arr2) //[ '北京', '重庆', '北京', '广东' ]
console.log(arr3) //1
//返回传入一个测试条件(函数)符合条件的数组第一个元素索引
arr.findIndex(function(currentValue, index, arr), thisValue) 

迭代方法

arr.every(function(currentValue,index,arr), thisValue)

用于检测数组所有元素是否都符合指定条件(通过函数提供),返回boolean 传入的函数必须对每一项都返回 true ,它才会返回 true ;否则,它就返回 false

let arr = ['重庆1','北京1','上海1','天津1','四川1','湖南']
let b = arr.every(item=>item.lastIndexOf('1') > -1)
console.log(b);//false

arr.filter(fn(currentValue,index,arr), thisValue)

检查指定数组中符合条件的所有元素,返回新数组

//过滤掉相等,返回不相等的
this.todos.filter(todo => todo.id !== id)

//过滤掉isActive不为true的
let arr = [{name:'重庆',isActive:false,py:'chongqing'},{name:'上海',isActive:false,py:'shanghai'},{name:'北京',isActive:true,py:'beijing'}]
let b = arr.filter(item=>item.isActive==true)
console.log(b);//[ { name: '北京', isActive: true, py: 'beijing' } ]

arr.forEach((item,index)=>{})

arr.map(function(currentValue,index,arr), thisValue)

创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果

//操作原数组
let arr = [{name:'重庆',isActive:false,py:'chongqing'},{name:'上海',isActive:false,py:'shanghai'},{name:'北京',isActive:true,py:'beijing'}]
arr.map((item,index,array)=>item['coordinate']='123,456')
console.log(arr);
/*
输出:
[
  {name: '重庆',isActive: false,py: 'chongqing',coordinate: '123,456'},
  { name: '上海',isActive: false,py: 'shanghai',coordinate: '123,456'},
  { name: '北京', isActive: true, py: 'beijing', coordinate: '123,456' }
]
*/ 


let numbers = [1, 2, 3, 4, 5, 4, 3, 2, 1];
let mapResult = numbers.map((item, index, array) => item * 2);
console.log(mapResult);//返回一个新的数组
console.log(numbers);//原数组不变



Array.prototype.map.call(arr,fun)

arr.some(function(currentValue,index,arr),thisValue)

用于检测数组中的元素是否满足指定条件(函数提供) 只要有一项让传入的函数返回 true ,它就会返回 true

let arr = ['重庆1','北京1','上海1','天津1','四川1','湖南']
let b = arr.some(item=>item.lastIndexOf('1') > -1)
console.log(b);//true

归并方法

arr.reduce(function(total, currentValue, currentIndex, arr), initialValue)

接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值 函数接收 4 个参数:上一个归并值、当前项、当前项的索引和数组本身。

let values = [1, 2, 3, 4, 5];
let sum = values.reduce((prev, cur, index, array) => prev + cur);
console.log(sum); // 15
//第一次执行归并函数时, prev 是 1, cur 是 2。第二次执行时, prev 是 3(1 + 2), cur 是 3(数组第三项)。如此递进,直到把所有项都遍历一次,最后返回归并结果。

arr.reduceRight(function(total, currentValue, currentIndex, arr), initialValue)

的功能和 reduce() 功能是一样的,不同的是 reduceRight() 从数组的末尾向前将数组中的数组项做累加 函数接收 4 个参数:上一个归并值、当前项、当前项的索引和数组本身。

let values = [1, 2, 3, 4, 5];
let sum = values.reduceRight(function(prev, cur, index, array){
return prev + cur;
});
console.log(sum); // 15
//第一次调用归并函数时 prev 是 5,而 cur 是 4。当然,最终结果相同,因为归并操作都是简单的加法。

数组去重

1、利用ES6 Set去重(ES6中最常用)


//不考虑兼容性,这种去重的方法代码最少。这种方法还无法去掉“{}”空对象,后面的高阶方法会添加去掉重复“{}”的方法。
function unique (arr) {
  return Array.from(new Set(arr))
}
简约写法 [...new Set(arr)] 

2、利用for嵌套for,然后splice去重(ES5中最常用)

//双层循环,外层循环元素,内层循环时比较值。值相同时,则删去这个值。
function unique(arr){            
       for(var i=0; i<arr.length; i++){
            for(var j=i+1; j<arr.length; j++){
                if(arr[i]==arr[j]){         //第一个等同于第二个,splice方法删除第二个
                    arr.splice(j,1);
                    j--;
                }
            }
        }
	return arr;
}

3、利用indexOf去重

//新建一个空的结果数组,for 循环原数组,判断结果数组是否存在当前元素,如果有相同的值则跳过,不相同则push进数组。
function unique(arr) {
    if (!Array.isArray(arr)) {
        console.log('type error!')
        return
    }
    var array = [];
    for (var i = 0; i < arr.length; i++) {
        if (array .indexOf(arr[i]) === -1) {
            array .push(arr[i])
        }
    }
    return array;
}

4、利用sort()

//利用sort()排序方法,然后根据排序后的结果进行遍历及相邻元素比对
function unique(arr) {
    if (!Array.isArray(arr)) {
        console.log('type error!')
        return;
    }
    arr = arr.sort()
    var arrry= [arr[0]];
    for (var i = 1; i < arr.length; i++) {
        if (arr[i] !== arr[i-1]) {
            arrry.push(arr[i]);
        }
    }
    return arrry;
}

5、利用includes

function unique(arr) {
    if (!Array.isArray(arr)) {
        console.log('type error!')
        return
    }
    var array =[];
    for(var i = 0; i < arr.length; i++) {
            if( !array.includes( arr[i]) ) {//includes 检测数组是否有某个值
                    array.push(arr[i]);
              }
    }
    return array
}

6、利用hasOwnProperty

//利用hasOwnProperty 判断是否存在对象属性
function unique(arr) {
    var obj = {};
    return arr.filter(function(item, index, arr){
        return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
    })
}

7、利用filter

function unique(arr) {
  return arr.filter(function(item, index, arr) {
    //当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
    return arr.indexOf(item, 0) === index;
  });
}

8、利用递归去重

function unique(arr) {
        var array= arr;
        var len = array.length;

    array.sort(function(a,b){   //排序后更加方便去重
        return a - b;
    })

    function loop(index){
        if(index >= 1){
            if(array[index] === array[index-1]){
                array.splice(index,1);
            }
            loop(index - 1);    //递归loop,然后数组去重
        }
    }
    loop(len-1);
    return array;
}

9、利用Map数据结构去重

//创建一个空Map数据结构,遍历需要去重的数组,把数组的每一个元素作为key存到Map中。由于Map中不会出现相同的key值,所以最终得到的就是去重后的结果。
function arrayNonRepeatfy(arr) {
  let map = new Map();
  let array = new Array();  // 数组用于返回结果
  for (let i = 0; i < arr.length; i++) {
    if(map .has(arr[i])) {  // 如果有该key值
      map .set(arr[i], true); 
    } else { 
      map .set(arr[i], false);   // 如果没有该key值
      array .push(arr[i]);
    }
  } 
  return array ;
}

10、利用reduce+includes

function unique(arr){
    return arr.reduce((prev,cur) => prev.includes(cur) ? prev : [...prev,cur],[]);
}

中文数组对象排序

let arrObj = [{label: "爱尔兰", value: "0372"},
{label: "文莱", value: "0096"},
{label: "法国", value: "0250"},
{label: "尼泊尔", value: "0524"},
{label: "芬兰", value: "0246"},
{label: "约旦", value: "0400"},
{label: "罗马尼亚", value: "0642"},
{label: "伊拉克", value: "0368"},
{label: "俄罗斯", value: "0643"},
{label: "泰国", value: "0764"},
 {label: "加拿大", value: "0124"},
 {label: "斐济", value: "0242"},
 {label: "墨西哥", value: "0484"},
 {label: "伊朗", value: "0364"}]

 function sortChinese (arr, dataLeven) { 
  function getValue (option) { 
    if (!dataLeven) return option
    var data = option
    dataLeven.split('.').filter(function (item) {
      data = data[item]
    })
    return data + ''
  }
  arr.sort(function (item1, item2) {
    return getValue(item1).localeCompare(getValue(item2), 'zh-Hans-CN', {sensitivity: 'accent'});
  })
}
sortChinese(arrObj, 'label') 
console.log(arrObj);

Array遍历

//for...of...
let arr = ["a","b"]
for (const item of arr) {
  console.log(item);
  
}

//forEach()
arr.forEach((item,index)=>{
    
})

//for...in...
let arr = ["a","b","c"]
for (const i in arr) {
   console.log(arr[i]);
}

arr.length

#属性可设置或返回数组中元素的数目
arr.length

Math.max.apply(null,arr)

Math.max.apply(null,arr)  //返回数组中的最大值

Array.isArray()

Array.isArray(paramet) //判断是否是数组

arr.unshift()

arr.unshift(item1,item2, ..., itemX) //可向数组的开头添加一个或更多元素,并返回新的长度

arr.toString()

arr.toString()  //方法可把数组转换为字符串,并返回结果

arr.flatMap()

arr.flatMap(fn) //把二维数组转成一位数组

let arr keys.flatMap(key=>goodsInfo[key])

==ES6语法==

扩展运算符

//1.复制数组
let arr = ['a','b','c']
let arr1 = [...arr]
console.log(ar1) //[ 'a', 'b', 'c' ]

//2.合并数组(浅拷贝)
let arr = ['a','b','c']
let arr2 = ['g','t']
let a = [...arr,...arr2]
console.log(a) //[ 'a', 'b', 'c', 'g', 't' ]

数组解构

const arr = [100,200,300]
const [a,b,c] = arr
console.log(a,b,c)// 100,200,300

const [,b,] = arr
console.log(b) //200

Array.from()

//用于将两类对象转为真正的数组:类似数组的对象,和可遍历的对象
let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
};

// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']

// ES6的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']



//Array.from还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。
Array.from([1, 2, 3], (x) => x * x)
// [1, 4, 9]

console.log(Array.from("Matt")); // ["M", "a", "t", "t"]

Array.of()

//方法用于将一组值,转换为数组。
Array.of(3, 11, 8) // [3,11,8]


//Array方法没有参数、一个参数、三个参数时,返回结果都不一样。只有当参数个数不少于 2 个时,Array()才会返回由参数组成的新数组。参数个数只有一个时,实际上是指定数组的长度。
Array() // []
Array(3) // [, , ,]
Array(3, 11, 8) // [3, 11, 8]



//Array.of基本上可以用来替代Array()或new Array(),并且不存在由于参数不同而导致的重载。它的行为非常统一。
Array.of() // []
Array.of(undefined) // [undefined]
Array.of(1) // [1]
Array.of(1, 2) // [1, 2]

//Array.of方法可以用下面的代码模拟实现。
function ArrayOf(){
  return [].slice.call(arguments);
}

arr.entries()

//用于遍历数组,对键值对的遍历。
let arr = ['上海','重庆','北京','广东']

for (let [index, elem] of arr.entries()) {
  console.log(index, elem);  //0 '上海',  1 '重庆',  2 '北京',  3 '广东'
}

arr.keys()

#用于遍历数组,对键名的遍历
let arr = ['上海','重庆','北京','广东']

for (let index of arr.keys()) {
  console.log(index); //0,1,2,3
}

arr.values()

//用于遍历数组,对键值的遍历
let arr = ['上海','重庆','北京','广东']

for (let elem of arr.values()) {
  console.log(elem); //上海 重庆 北京 广东
}

arr.flat()

//用于将嵌套的数组“拉平”,变成一维的数组。该方法返回一个新数组,对原数据没有影响。
let arr = ['上海','重庆','北京','广东',['深圳','武汉']]

let arr1 = arr.flat(2)
console.log(arr1) //['上海','重庆','北京','广东','深圳','武汉']

arr.flatMap()

//对原数组的每个成员执行一个函数(相当于执行Array.prototype.map()),然后对返回值组成的数组执行flat()方法。该方法返回一个新数组,不改变原数组。

// 相当于 [[2, 4], [3, 6], [4, 8]].flat()
[2, 3, 4].flatMap((x) => [x, x * 2])
// [2, 4, 3, 6, 4, 8]

定型数组

ArrayBuffer

const buf = new ArrayBuffer(32);

ArrayBuffer.prototype.byteLength

ArrayBuffer实例的byteLength属性,返回所分配的内存区域的字节长度。

const buffer = new ArrayBuffer(32);
buffer.byteLength
// 32

ArrayBuffer.prototype.slice()

ArrayBuffer实例有一个slice方法,允许将内存区域的一部分,拷贝生成一个新的ArrayBuffer对象。

const buffer = new ArrayBuffer(8);
const newBuffer = buffer.slice(0, 3);

ArrayBuffer.isView()

ArrayBuffer有一个静态方法isView,返回一个布尔值,表示参数是否为ArrayBuffer的视图实例。这个方法大致相当于判断参数,是否为TypedArray实例或DataView实例。

const buffer = new ArrayBuffer(8);
ArrayBuffer.isView(buffer) // false

const v = new Int32Array(buffer);
ArrayBuffer.isView(v) // true

DataView

第一种允许你读写 ArrayBuffer 的视图是 DataView 。这个视图专为文件 I/O 和网络 I/O 设计,其API 支持对缓冲数据的高度控制,但相比于其他类型的视图性能也差一些。 DataView 对缓冲内容没有任何预设,也不能迭代。

const buf = new ArrayBuffer(32);
const dataView = new DataView(buf);
dataView.getUint8(0) // 0

TypedArray

普通数组的操作方法和属性,对 TypedArray 数组完全适用

// 创建一个8字节的ArrayBuffer
const b = new ArrayBuffer(8);

// 创建一个指向b的Int32视图,开始于字节0,直到缓冲区的末尾
const v1 = new Int32Array(b);

// 创建一个指向b的Uint8视图,开始于字节2,直到缓冲区的末尾
const v2 = new Uint8Array(b, 2);

// 创建一个指向b的Int16视图,开始于字节2,长度为2
const v3 = new Int16Array(b, 2, 2);

TypedArray视图支持的数据类型一共有 9 种(DataView视图支持除Uint8C以外的其他 8 种)。

数据类型字节长度含义对应的 C 语言类型值的范围
Int818 位带符号整数signed char-128~127
Uint818 位不带符号整数unsigned char0~255
Uint8C18 位不带符号整数(自动过滤溢出)unsigned char
Int16216 位带符号整数short-32768~32767
Uint16216 位不带符号整数unsigned short0~65535
Int32432 位带符号整数int-2147483648~2147483647
Uint32432 位不带符号的整数unsigned int0~4294967295
Float32432 位浮点数float-3.4e+38~+3.4e+38
Float64864 位浮点数double-1.7e+308~+1.7e+308

注意,二进制数组并不是真正的数组,而是类似数组的对象。