【JS】9--數(shù)組

數(shù)組

知識(shí)匯總

前置知識(shí): 數(shù)組是一個(gè)有序的數(shù)據(jù)集合纵苛,可使用數(shù)組名稱和索引進(jìn)行訪問盾致。

let arr = [1,2,3];
arr[0] = 1;

在JavaScript中數(shù)組沒有明確數(shù)據(jù)類型。

let arr = [1, 'hi', undefined, fun()];

一 . 創(chuàng)建數(shù)組

創(chuàng)建數(shù)組方法有3種:

let arr = new Array(ele1, ele2, ele3, ..., eleN);
let arr = Array(ele1, ele2, ele3, ..., eleN);
let arr = [ele1, ele2, ele3, ..., eleN];

上面是已知數(shù)組元素毕谴,另外一種還有創(chuàng)建一個(gè)長度不為0成畦,且有沒有任何元素的數(shù)組

let len = 5;

let arr = new Array(len); // 方法1
let arr = Array(len);     // 方法2
let arr = [];             // 方法3
arr.length = len;

若傳入的數(shù)組長度不是整數(shù),則報(bào)錯(cuò):

let arr = new Array(3.5); 
let arr = Array(3.5); 
let arr = [];
arr.length = 3.5;
//Uncaught RangeError: Invalid array length

其中要注意這兩種創(chuàng)建方法是不同的:

let arr1 = new Array(4);   // [empty × 4]
let arr2 = [4];            // [4]
for(let k in arr1){
    console.log(k);
}  // undefined
for(let k in arr2){
    console.log(k);
}  // 0

 var 變量名=new Array( ); // 新建一個(gè)長度為零的數(shù)組

 var 變量名=new Array( n );// 新建一個(gè)長度為N的數(shù)組

 var 變量名=new Array( 元素1,元素2,元素3,…); // 新建一個(gè)指定長度的數(shù)組涝开,并賦值

 var 變量名=[ 元素1,元素2,元素3,…];  // 簡單方法

=========================================================

二 . 使用數(shù)組

1. 簡單使用

a. 獲取數(shù)組指定位置的值:
let a = [1,2,5];
a[0];  // 1
a[2];  // 5
a[3];  // undefined

獲取數(shù)組長度:length
let a = [1,2,5];
a.length;    // 3
a["length"]; // 3

設(shè)置數(shù)組指定位置的值:
let a = [1,2,5];
a[0] = 9;
a[2] = 99;
a[3] = 999;

b. 理解數(shù)組length
  • 數(shù)組的索引值是從0開始循帐,即上面數(shù)組索引0的是1,索引1的值是2,依次下去舀武。
  • 數(shù)組length永遠(yuǎn)返回的是數(shù)組最后一個(gè)元素的索引加1拄养。
  • 可通過arr.length = 0來清空數(shù)組。
  • 可通過arr.length = len來設(shè)置數(shù)組長度银舱。

===========================================================

三 . 操作數(shù)組

1. 遍歷數(shù)組

遍歷數(shù)組就是以某種方法處理數(shù)組的每個(gè)元素瘪匿,簡單如下:

a. 使用for循環(huán):
let arr = ["pingan", "leo", "robin"];
for (let i = 0; i<arr.length; i++){
    // 處理元素的操作
    console.log(`第${i}個(gè)元素是:${arr[i]};`)
}
// 第0個(gè)元素是:pingan寻馏;
// 第1個(gè)元素是:leo棋弥;
// 第2個(gè)元素是:robin;
b. 使用 for...in
let arr = ["pingan", "leo", "robin"];
for(let i in arr){
    console.log(`第${i}個(gè)元素是:${arr[i]}诚欠;`)
}
c. 使用forEach

arr.forEach(callback) 接收一個(gè)回調(diào)方法顽染。
callback(val, index, array) : 接收三個(gè)參數(shù):

  • val : 當(dāng)前處理的元素;
  • index : 當(dāng)前處理的元素的索引轰绵;
  • array : 正在處理的數(shù)組粉寞;

可參考MDN Array.prototype.forEach 的詳細(xì)介紹。

let arr = ["pingan", "leo", "robin"];
arr.forEach(function(val, i, array){
    console.log(`第${i}個(gè)元素是:${val}左腔;`)
})

更多方法:https://www.cnblogs.com/woshidouzia/p/9304603.html

==========================================================

2. 數(shù)組排序

從大到小

  • sort() 排序
  • reverse() 翻轉(zhuǎn)
  • sort((a,b)=>a>b?-1:1)

a. reverse()

var arr = [8,4,9,1];
console.log(arr.reverse());   //  [1, 9, 4, 8]
console.log(arr);   //  [1, 9, 4, 8]

可以看出唧垦,reverse()會(huì)直接改變原數(shù)組,并且返回值也是倒序后的數(shù)組翔悠。

b. sort()

記得當(dāng)年學(xué)C語言時(shí),要學(xué)各種各樣的排序算法野芒,比如經(jīng)典的冒泡排序法蓄愁、二分排序法等,現(xiàn)在拋開這些算法不說狞悲,JS就自帶原生的排序函數(shù)撮抓,用起來非常方便,它就是sort()摇锋。

不傳參數(shù)
var arr = [8,4,9,1];
console.log(arr.sort());   //  [1, 4, 8, 9]
console.log(arr);   //  [1, 4, 8, 9]

我們再來看下一個(gè)例子:

var arr = [8,90,9,16];
console.log(arr.sort());  //  [16, 8, 9, 90]

可以看出丹拯,sort()不傳參數(shù)時(shí)會(huì)按升序方式對數(shù)組項(xiàng)進(jìn)行排序站超,并且與reverse()一樣既改變原數(shù)組,同時(shí)返回的也是排序后的數(shù)組乖酬。

案例2 最終排序返回的不應(yīng)該是[8, 9, 16, 90] 死相,返回的是[16, 8, 9, 90],這是因?yàn)橐瘢瑂ort()并不是按照數(shù)值進(jìn)行排序算撮,而是按字符串字母的ASCII碼值進(jìn)行比較排序的,所以當(dāng)數(shù)組項(xiàng)為數(shù)字時(shí)县昂,sort()也會(huì)自動(dòng)先將數(shù)字轉(zhuǎn)換成字符串肮柜,然后再按字母比較的規(guī)則進(jìn)行排序處理。

現(xiàn)在我們再回頭看看前面兩個(gè)例子倒彰。當(dāng)arr為[8,4,9,1]時(shí)审洞,數(shù)組每一項(xiàng)轉(zhuǎn)換成字符串后進(jìn)行排序的結(jié)果正好與數(shù)字排序結(jié)果相同;而當(dāng)arr為[8,90,9,16]時(shí)待讳,數(shù)組每一項(xiàng)轉(zhuǎn)換成字符串后就得按順序一位一位進(jìn)行比較芒澜,比如升序排序時(shí),“16”應(yīng)該排在最前面耙箍,因?yàn)椤?6”的第一位是“1”撰糠,比“8”和“9”的ASCII碼值都要小。

傳入一個(gè)函數(shù)

這個(gè)函數(shù)參數(shù)功能其實(shí)很簡單辩昆,實(shí)際上就是告訴sort()排序方式到底是升序還是降序

var arr = [8,90,9,16];
// 升序
console.log(arr.sort(function (a, b) {
    return a - b;
}));    //  [8, 9, 16, 90]

// 降序
console.log(arr.sort(function (a, b) {
    return b - a;
}));   //  [90, 16, 9, 8]

這種用法的規(guī)則是阅酪,當(dāng)sort()傳入函數(shù)中的第一個(gè)參數(shù)a位于第二個(gè)參數(shù)b之前,則返回一個(gè)負(fù)數(shù)汁针,相等則返回0术辐,a位于b之后則返回正數(shù)。

比如施无,當(dāng)要做升序排序時(shí)辉词,我們需要想到前面的數(shù)肯定是要比后面的數(shù)小,所以傳入的這個(gè)函數(shù)參數(shù)返回值應(yīng)該要是個(gè)負(fù)數(shù)猾骡,因此函數(shù)參數(shù)返回a - b瑞躺。

注:冒泡排序、快速排序兴想、希爾排序幢哨、插入排序
http://www.reibang.com/p/da9e31c485c2

========================================================

3. 數(shù)組去重

方法一:利用ES6的Array.from() 擴(kuò)展運(yùn)算符 以及 Set

Set:一個(gè)可以是任何類型的獨(dú)一無二的值的集合.

  function unique(arr){
      return Array.from(new Set(arr));
  }

你也可以這樣寫:

var arr = [1,2,3,4,2,3,4,8];
  function unique(arr){
      return [...new Set(arr)];
  }
console.log(unique(arr));

方法二:遍歷數(shù)組,建立新數(shù)組嫂便,利用indexOf判斷是否存在于新數(shù)組中捞镰,不存在則push到新數(shù)組,最后返回新數(shù)組

index 差下標(biāo)不同去重
1. 當(dāng)前 會(huì)有個(gè)下標(biāo)
2. indexOf 查找也會(huì)返回一個(gè)下標(biāo)
3. 如果兩個(gè)下標(biāo)不同說明是重復(fù)的。

indexOf() :方法可返回某個(gè)指定的字符串值在字符串中首次出現(xiàn)的位置岸售。如果沒有則返回-1

var arr = [1,2,3,4,2,3,4,8];
 function unique(arr){
     var newArr = [];
     for(var i in arr) {
         if(newArr.indexOf(arr[i]) == -1) {
             newArr.push(arr[i])
         }
     }
     return newArr;
 }
console.log(unique(arr));

方法三:利用for嵌套for践樱,然后splice去重(ES5中最常用)

var arr = [1,2,3,4,2,3,4,8];
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]){         //第一個(gè)等同于第二個(gè),splice方法刪除第二個(gè)
                     arr.splice(j,1);
                     j--;
                }
            }
        }
return arr;
}
console.log(unique(arr));

方法四:先排序凸丸,新數(shù)組最后一項(xiàng)為舊數(shù)組第一項(xiàng)拷邢,每次插入判斷新數(shù)組最后一項(xiàng)是否與插入項(xiàng)相等

function unique(arr) {
    var newArr = [];
    var end; //end其實(shí)就是一道卡
    arr.sort();
    end = arr[0];
    newArr.push(arr[0]);
    for (var i = 1; i < arr.length; i++) {
        if (arr[i] != end) {
            newArr.push(arr[i]);
            end = arr[i]; //更新end
        }
    }
    return newArr;
}

filter去重

var arr = [1, 2, 2, 3, 4, 5, 5, 6, 7, 7];
var arr2 = arr.filter(function(x, index,self) { 
return self.indexOf(x)===index;
}); 
console.log(arr2); //[1, 2, 3, 4, 5, 6 ,7]

更多方法:https://segmentfault.com/a/1190000016418021?utm_source=tag-newest

=========================================================

4. 數(shù)組與字符串轉(zhuǎn)換

數(shù)組轉(zhuǎn)字符串 a.join
字符串轉(zhuǎn)數(shù)組s.split

=====================================================

5. 數(shù)組合并,拷貝 甲雅,深拷貝 有哪些方法

slice和concat方法淺拷貝和深拷貝
array_merge()合并兩個(gè)數(shù)組
concat將a數(shù)組合并到b數(shù)組中去
遍歷解孙,遞歸實(shí)現(xiàn)深拷貝
轉(zhuǎn)json字符串,字符串轉(zhuǎn)json 實(shí)現(xiàn)深拷貝
JSON.stringify(obj) JSON.parse(str)

=============================================================

四. 數(shù)組方法(增刪改查)

方法名稱 方法介紹
------------------------------------------------------------
unshift() 向數(shù)組的開頭添加一個(gè)或更多元素抛人,并返回新的長度弛姜。
push() 向數(shù)組的末尾添加一個(gè)或更多元素,并返回新的長度妖枚。
splice(from,length,add) 刪除元素廷臼,并向數(shù)組添加新元素。
-----------------------------------------------------------
pop() 刪除并返回?cái)?shù)組的最后一個(gè)元素
shift() 刪除并返回?cái)?shù)組的第一個(gè)元素
splice(from,len,add) 刪除元素绝页,并向數(shù)組添加新元素荠商。
----------------------------------------------------------
concat() 連接兩個(gè)或更多的數(shù)組,并返回結(jié)果续誉。
join() 把數(shù)組的所有元素放入一個(gè)字符串莱没。元素通過指定的分隔符進(jìn)行分隔。
reverse() 顛倒數(shù)組中元素的順序酷鸦。
sort() 對數(shù)組的元素進(jìn)行排序
toString() 把數(shù)組轉(zhuǎn)換為字符串饰躲,并返回結(jié)果。
toSource() 返回該對象的源代碼臼隔。
toLocaleString() 把數(shù)組轉(zhuǎn)換為本地?cái)?shù)組嘹裂,并返回結(jié)果。
valueOf() 返回?cái)?shù)組對象的原始值
-------------------------------------------------------------
indexOf() 在數(shù)組中搜索指定元素并返回第一個(gè)匹配的 索引
lastIndexOf() 在數(shù)組中搜索指定元素并返回最后一個(gè)匹配的 索引
slice(start,end) 從某個(gè)已有的數(shù)組返回選定的 元素 ,索引start到end,包start不包end
includes() 找到返回true
find() find()方法用于找出第一個(gè)符合條件的數(shù)組成員value,參數(shù)為一個(gè)回調(diào)函數(shù)斑鼻,所有成員依次執(zhí)行該回調(diào)函數(shù),返回第一個(gè)返回值為true的成員泊愧,如果沒有一個(gè)符合則返回undefined。
findIndex() es6 findIndex()方法與find()類似盛正,返回第一個(gè)符合條件的數(shù)組成員的位置删咱,如果都不符合則返回-1

可參考W3school JavaScript Array 對象 的詳細(xì)介紹。

1. concat()

連接兩個(gè)或更多的數(shù)組蛮艰,并返回一個(gè)新數(shù)組腋腮。

  • 語法:
    arr.concat(a1, a2, ..., an);
  • 參數(shù):
    arr:目標(biāo)數(shù)組;
    a1,a2,...,an:需要合并的元素壤蚜;
let a1 = [1,2,3];
let a2 = [9,99,999];
let a = a1.concat(a2);
// [1, 2, 3, 9, 99, 999]

2. join()

使用指定分隔符即寡,連接兩個(gè)或多個(gè)數(shù)組的元素,返回一個(gè)字符串袜刷。

  • 語法:
    arr.join(sep);
  • 參數(shù):
    arr:目標(biāo)數(shù)組聪富;
    sep:連接的分隔符,默認(rèn)值為“,”著蟹;
let arr = ["pingan", "leo", "robin"];
arr.join();    // "pingan,leo,robin"
arr.join("");  // "pinganleorobin"
arr.join(","); // "pingan,leo,robin"

3. pop()和push()

  • pop(): 刪除并返回?cái)?shù)組最后一個(gè)元素墩蔓,改變原數(shù)組

  • push(item): 向數(shù)組末尾添加一個(gè)或多個(gè)元素萧豆,改變原數(shù)組奸披,返回新的數(shù)組長度。
    方便記憶和理解:兩個(gè)都是從數(shù)組末尾操作涮雷,pop()是刪除最后一個(gè)元素阵面,push()是向最后一位添加新的元素。

let arr = ["pingan", "leo"];
let a1 = arr.pop();              // "leo"
let a2 = arr.push("robin","hi"); // 3
arr;   // ["pingan", "robin", "hi"]

4. shift()和unshift()

  • shift(): 刪除并返回?cái)?shù)組第一個(gè)元素洪鸭,改變原數(shù)組样刷。
  • unshift(item): 向數(shù)組頭部添加一個(gè)或多個(gè)元素,改變原數(shù)組览爵,返回新的數(shù)組長度置鼻。

方便記憶和理解:兩個(gè)都是從數(shù)組頭部操作,shift()是刪除第一個(gè)元素蜓竹,unshift()是向第一位添加新的元素箕母。

let arr = ["pingan", "leo"];
let a1 = arr.shift();               // "pingan"
let a2 = arr.unshift("robin","hi"); // 3
arr;   // ["robin", "hi", "leo"]

5. reverse()

顛倒數(shù)組中元素的順序,改變原數(shù)組梅肤。

let arr = [1, 2, 3, 4];
arr.reverse();  // [4, 3, 2, 1]

6. slice()

用于提取數(shù)組中一個(gè)片段司蔬,作為新數(shù)組返回。
slice(start[,end]): 接收2個(gè)參數(shù):

  • start: 必需姨蝴,指定起始索引俊啼,若負(fù)數(shù)則從數(shù)組最后開始算起,-1為倒數(shù)第一位左医,-2為倒數(shù)第二位授帕,以此類推。
  • end: 可選浮梢,指定結(jié)束索引跛十,若沒傳則表示到數(shù)組結(jié)束。

注意
end若有指定的話秕硝,是不包含end索引上的值芥映。

let arr = [1, 2, 3, 5, 6];
let a1 = arr.slice(2);    // [3, 5, 6]
let a2 = arr.slice(2,3);  // [3]

7. splice()

從數(shù)組中刪除指定索引開始的項(xiàng)目,然后返回被刪除的項(xiàng)目。

  • 語法: arr.splice(index, num, a1, a2,...,an);
  • 參數(shù):
    index: 必需奈偏,起始位置的索引坞嘀,若負(fù)數(shù)則從數(shù)組最后開始算起;
    num:必需惊来,刪除的數(shù)量丽涩,若為0則不刪除;
    a1,a2,...an:可選裁蚁,為數(shù)組添加的元素矢渊;
let arr = [1, 2, 3, 4];
let a = arr.splice(1, 2, "hi", "leo");
// a =>  [2, 3]
// arr =>  [1, "hi", "leo", 4]

8. sort()

對數(shù)組的元素進(jìn)行排序,改變原數(shù)組枉证。
可接受一個(gè)回調(diào)方法作為比較函數(shù)矮男,來決定排序方式。
比較函數(shù)應(yīng)該具有兩個(gè)參數(shù) ab室谚,返回值如下:
a 小于 b昂灵,在排序后的數(shù)組中 a 應(yīng)該出現(xiàn)在 b 之前,則返回一個(gè)小于 0 的值舞萄。 若 a 等于 b眨补,則返回 0。 若 a 大于 b倒脓,則返回一個(gè)大于 0 的值撑螺。

let a1 = [1,3,6,9,10];
a1.sort(); // [1, 10, 3, 6, 9]
a1.sort(function(a,b){
    return a > b ? 1 : a < b ? -1 : 0;
})         // [1, 3, 6, 9, 10]

9. indexOf()和lastIndexOf()

兩者都是在數(shù)組搜索指定元素,只是indexOf()返回的是搜索到的第一個(gè)元素的索引崎弃,而lastIndexOf()返回的是搜索到的最后一個(gè)元素的索引甘晤。
語法:
indexOf(ele[,start])lastIndexOf(ele[,start]);
參數(shù):

  • ele: 需要搜索的元素。
  • start: 開始搜索的索引饲做。
let arr = ["hh1", "hh2", "hh2", "hh2", "hh3", "hh4"];
let a1 = arr.indexOf("hh2");      // 1
let a2 = arr.lastIndexOf("hh2");  // 3
let a3 = arr.indexOf("hh2",2);    // 2

10. find()和findIndex()

find()方法用于找出第一個(gè)符合條件的數(shù)組成員线婚,參數(shù)為一個(gè)回調(diào)函數(shù),所有成員依次執(zhí)行該回調(diào)函數(shù)盆均,返回第一個(gè)返回值為true的成員塞弊,如果沒有一個(gè)符合則返回undefined。

[1,2,3,4,5].find( a => a < 3 ); // 1
回調(diào)函數(shù)接收三個(gè)參數(shù)泪姨,當(dāng)前值游沿、當(dāng)前位置和原數(shù)組。
[1,2,3,4,5].find((value, index, arr) => {
    // ...
});

findIndex()方法與find()類似肮砾,返回第一個(gè)符合條件的數(shù)組成員的位置诀黍,如果都不符合則返回-1。

[1,2,3,4].findIndex((v,i,a)=>{
    return v>2;
}); // 2

五 . 數(shù)組高階方法(迭代)

  • ES6
    flat()
    flatMap()
    find()
    findIndex()
    fill()
    includes()
方法名稱 方法介紹
forEach() 為數(shù)組中的每個(gè)元素執(zhí)行一次回調(diào)函數(shù)仗处。
every() 如果數(shù)組中的每個(gè)元素都滿足測試函數(shù)眯勾,則返回 true枣宫,否則返回 false。
some() 如果數(shù)組中至少有一個(gè)元素滿足測試函數(shù)吃环,則返回 true镶柱,否則返回 false。
filter() 將所有在過濾函數(shù)中返回 true 的數(shù)組元素放進(jìn)一個(gè)新數(shù)組中并返回模叙。
map() 返回一個(gè)由回調(diào)函數(shù)的返回值組成的新數(shù)組。
reduce() 從左到右為每個(gè)數(shù)組元素執(zhí)行一次回調(diào)函數(shù)鞋屈,并把上次回調(diào)函數(shù)的返回值放在一個(gè)暫存器中傳給下次回調(diào)函數(shù)范咨,并返回最后一次回調(diào)函數(shù)的返回值。
reduceRight() 從右到左為每個(gè)數(shù)組元素執(zhí)行一次回調(diào)函數(shù)厂庇,并把上次回調(diào)函數(shù)的返回值放在一個(gè)暫存器中傳給下次回調(diào)函數(shù)渠啊,并返回最后一次回調(diào)函數(shù)的返回值。

以下是ES6規(guī)范新增的數(shù)組方法:

方法名稱 方法介紹
keys() 返回一個(gè)數(shù)組迭代器對象权旷,該迭代器會(huì)包含所有數(shù)組元素的鍵替蛉。
values() 返回一個(gè)數(shù)組迭代器對象,該迭代器會(huì)包含所有數(shù)組元素的值拄氯。
entries() 返回一個(gè)數(shù)組迭代器對象躲查,該迭代器會(huì)包含所有數(shù)組元素的鍵值對。
find() 找到第一個(gè)滿足測試函數(shù)的元素并返回那個(gè)元素的值译柏,如果找不到镣煮,則返回 undefined。
findIndex() 找到第一個(gè)滿足測試函數(shù)的元素并返回那個(gè)元素的索引鄙麦,如果找不到典唇,則返回 -1。

可參考MDN Array 的詳細(xì)介紹胯府。

1. forEach()

對數(shù)組的每個(gè)元素執(zhí)行一次提供的函數(shù)介衔。

語法:
arr.forEach(callback)

參數(shù):
callback(val, index, arr) : 需要執(zhí)行的函數(shù)骂因,接收三個(gè)參數(shù):

  • val : 正在處理的當(dāng)前元素;
  • index : 可選炎咖,正在處理的當(dāng)前元素的索引;
  • arr : 可選,正在操作的數(shù)組;
let a = [1,3,5,7];
a.forEach(function(val, index, arr){
    arr[index] = val * 2
})
a ; // [2, 6, 10, 14]

2. every()

測試數(shù)組的所有元素是否都通過了指定函數(shù)的測試寒波。
語法:
arr.every(callback)塘装。

參數(shù):
callback(val, index, arr) : 需要執(zhí)行的函數(shù),接收三個(gè)參數(shù):

  • val : 正在處理的當(dāng)前元素;
  • index : 可選影所,正在處理的當(dāng)前元素的索引;
  • arr : 可選蹦肴,正在操作的數(shù)組;

返回值:
若都通過返回true,否則返回false猴娩。

let a = [1, "", "aa", 13, 6];
let res = a.every(function(val, index, arr){
    return typeof val == "number";
})
res;// false

let b = [1, 2, 3];
let r = b.every(function(val, index, arr){
    return typeof val == "number";
})
r;  // true

3. some()

測試數(shù)組中的某些元素是否通過由提供的函數(shù)實(shí)現(xiàn)的測試阴幌。
語法:
arr.some(callback)勺阐。

參數(shù):
callback(val, index, arr) : 需要執(zhí)行的函數(shù),接收三個(gè)參數(shù):

  • val : 正在處理的當(dāng)前元素;
  • index : 可選矛双,正在處理的當(dāng)前元素的索引;
  • arr : 可選渊抽,正在操作的數(shù)組;

返回值:
若有一個(gè)通過返回true,否則返回false议忽。

let a = [1, "", "aa", 13, 6];
let res = a.some(function(val, index, arr){
    return typeof val == "number";
})
res;// true

let b = [1, 2, 3];
let r = b.some(function(val, index, arr){
    return typeof val == "number";
})
r;  // true

4. filter()

將所有在過濾函數(shù)中返回 true 的數(shù)組元素放進(jìn)一個(gè)新數(shù)組中并返回懒闷。

語法:
arr.filter(callback)

參數(shù):
callback(val, index, arr) : 需要執(zhí)行的函數(shù)栈幸,接收三個(gè)參數(shù):

  • val : 正在處理的當(dāng)前元素;
  • index : 可選愤估,正在處理的當(dāng)前元素的索引;
  • arr : 可選,正在操作的數(shù)組;

返回值:
一個(gè)返回通過測試的元素的數(shù)組速址,若都沒有則返回空數(shù)組玩焰。

let a = [1, "", "aa", 13, 6];
let res = a.filter(function(val, index, arr){
    return typeof val == "number";
})
res;//[1, 13, 6]

5. map()

傳入一個(gè)操作函數(shù),對每個(gè)元素執(zhí)行此方法芍锚,并返回一個(gè)執(zhí)行后的數(shù)組昔园。

語法:
arr.map(callback)

參數(shù):
callback(val, index, arr) : 需要執(zhí)行的函數(shù)并炮,接收三個(gè)參數(shù):

  • val : 正在處理的當(dāng)前元素;
  • index : 可選默刚,正在處理的當(dāng)前元素的索引;
  • arr : 可選,正在操作的數(shù)組;

返回值:
一個(gè)新數(shù)組逃魄,每個(gè)元素都是回調(diào)函數(shù)的結(jié)果羡棵。

let a = [1, 3, 5];
let b = a.map(function(val, index, arr){
    return val + 2;
})
b; //[3, 5, 7]

==========================================================

六 . 數(shù)組的拓展(ES6)

1. 拓展運(yùn)算符

拓展運(yùn)算符使用(...),類似rest參數(shù)的逆運(yùn)算嗅钻,將數(shù)組轉(zhuǎn)為用(,)分隔的參數(shù)序列皂冰。

console.log(...[1, 2, 3]);   // 1 2 3 
console.log(1, ...[2,3], 4); // 1 2 3 4

拓展運(yùn)算符主要使用在函數(shù)調(diào)用。

function f (a, b){
    console.log(a, b);
}
f(...[1, 2]); // 1 2

function g (a, b, c, d, e){
    console.log(a, b, c, d, e);
}
g(0, ...[1, 2], 3, ...[4]); // 0 1 2 3 4

若拓展運(yùn)算符后面是個(gè)空數(shù)組养篓,則不產(chǎn)生效果秃流。

[...[], 1]; // [1]

替代apply方法

// ES6之前
function f(a, b, c){...};
var a = [1, 2, 3];
f.apply(null, a);

// ES6之后
function f(a, b, c){...};
let a = [1, 2, 3];
f(...a);

// ES6之前
Math.max.apply(null, [3,2,6]);

// ES6之后
Math.max(...[3,2,6]);

拓展運(yùn)算符的運(yùn)用

  • (1)復(fù)制數(shù)組
    通常我們直接復(fù)制數(shù)組時(shí),只是淺拷貝柳弄,如果要實(shí)現(xiàn)深拷貝舶胀,可以使用拓展運(yùn)算符。
// 通常情況 淺拷貝
let a1 = [1, 2];
let a2 = a1; 
a2[0] = 3;
console.log(a1,a2); // [3,2] [3,2]

// 拓展運(yùn)算符 深拷貝
let a1 = [1, 2];
let a2 = [...a1];
// let [...a2] = a1; // 作用相同
a2[0] = 3;
console.log(a1,a2); // [1,2] [3,2]

  • (2)合并數(shù)組
    注意碧注,這里合并數(shù)組嚣伐,只是淺拷貝。
let a1 = [1,2];
let a2 = [3];
let a3 = [4,5];

// ES5 
let a4 = a1.concat(a2, a3);

// ES6
let a5 = [...a1, ...a2, ...a3];

a4[0] === a1[0]; // true
a5[0] === a1[0]; // true

  • (3)與解構(gòu)賦值結(jié)合
    與解構(gòu)賦值結(jié)合生成數(shù)組萍丐,但是使用拓展運(yùn)算符需要放到參數(shù)最后一個(gè)轩端,否則報(bào)錯(cuò)。
let [a, ...b] = [1, 2, 3, 4]; 
// a => 1  b => [2,3,4]

let [a, ...b] = [];
// a => undefined b => []

let [a, ...b] = ["abc"];
// a => "abc"  b => []

2. Array.from()

類數(shù)組對象可遍歷的對象逝变,轉(zhuǎn)換成真正的數(shù)組基茵。

// 類數(shù)組對象
let a = {
    '0':'a',
    '1':'b',
    length:2
}
let arr = Array.from(a);

// 可遍歷的對象
let a = Array.from([1,2,3]);
let b = Array.from({length: 3});
let c = Array.from([1,2,3]).map(x => x * x);
let d = Array.from([1,2,3].map(x => x * x));

3. Array.of()

將一組數(shù)值奋构,轉(zhuǎn)換成數(shù)組,彌補(bǔ)Array方法參數(shù)不同導(dǎo)致的差異拱层。

Array.of(1,2,3);    // [1,2,3]
Array.of(1).length; // 1

Array();       // []
Array(2);      // [,] 1個(gè)參數(shù)時(shí)弥臼,為指定數(shù)組長度
Array(1,2,3);  // [1,2,3] 多于2個(gè)參數(shù),組成新數(shù)組

4. find()和findIndex()

find()方法用于找出第一個(gè)符合條件的數(shù)組成員根灯,參數(shù)為一個(gè)回調(diào)函數(shù)径缅,所有成員依次執(zhí)行該回調(diào)函數(shù),返回第一個(gè)返回值為true的成員烙肺,如果沒有一個(gè)符合則返回undefined纳猪。

[1,2,3,4,5].find( a => a < 3 ); // 1

回調(diào)函數(shù)接收三個(gè)參數(shù),當(dāng)前值茬高、當(dāng)前位置和原數(shù)組。

[1,2,3,4,5].find((value, index, arr) => {
    // ...
});

findIndex()方法與find()類似假抄,返回第一個(gè)符合條件的數(shù)組成員的位置怎栽,如果都不符合則返回-1

[1,2,3,4].findIndex((v,i,a)=>{
    return v>2;
}); // 2

5. fill()

用于用指定值填充一個(gè)數(shù)組宿饱,通常用來初始化空數(shù)組熏瞄,并抹去數(shù)組中已有的元素。

new Array(3).fill('a');   // ['a','a','a']
[1,2,3].fill('a');        // ['a','a','a']

并且fill()的第二個(gè)和第三個(gè)參數(shù)指定填充的起始位置結(jié)束位置谬以。

[1,2,3].fill('a',1,2);//  [1, "a", 3]

6. entries(),keys(),values()

主要用于遍歷數(shù)組强饮,entries()對鍵值對遍歷,keys()對鍵名遍歷为黎,values()對鍵值遍歷邮丰。

for (let i of ['a', 'b'].keys()){
    console.log(i)
}
// 0
// 1

for (let e of ['a', 'b'].values()){
    console.log(e)
}
// 'a'
// 'b'

for (let e of ['a', 'b'].entries()){
    console.log(e)
}
// 0 'a'
// 1 'b'

7. includes()

用于表示數(shù)組是否包含給定的值,與字符串的includes方法類似铭乾。

[1,2,3].includes(2);     // true
[1,2,3].includes(4);     // false
[1,2,NaN].includes(NaN); // true

第二個(gè)參數(shù)為起始位置剪廉,默認(rèn)為0,如果負(fù)數(shù)炕檩,則表示倒數(shù)的位置斗蒋,如果大于數(shù)組長度,則重置為0開始笛质。

[1,2,3].includes(3,3);    // false
[1,2,3].includes(3,4);    // false
[1,2,3].includes(3,-1);   // true
[1,2,3].includes(3,-4);   // true

8. flat(),flatMap()

flat()用于將數(shù)組一維化泉沾,返回一個(gè)新數(shù)組,不影響原數(shù)組妇押。
默認(rèn)一次只一維化一層數(shù)組跷究,若需多層,則傳入一個(gè)整數(shù)參數(shù)指定層數(shù)敲霍。
若要一維化所有層的數(shù)組揭朝,則傳入Infinity作為參數(shù)队贱。

[1, 2, [2,3]].flat();        // [1,2,2,3]
[1,2,[3,[4,[5,6]]]].flat(3); // [1,2,3,4,5,6]
[1,2,[3,[4,[5,6]]]].flat('Infinity'); // [1,2,3,4,5,6]

flatMap()是將原數(shù)組每個(gè)對象先執(zhí)行一個(gè)函數(shù),在對返回值組成的數(shù)組執(zhí)行flat()方法潭袱,返回一個(gè)新數(shù)組柱嫌,不改變原數(shù)組。
flatMap()只能展開一層屯换。

[2, 3, 4].flatMap((x) => [x, x * 2]); 
// [2, 4, 3, 6, 4, 8] 

七 . 數(shù)組的拓展(ES7)

Array.prototype.includes()方法

includes()用于查找一個(gè)值是否在數(shù)組中编丘,如果在返回true,否則返回false彤悔。

['a', 'b', 'c'].includes('a');     // true
['a', 'b', 'c'].includes('d');     // false

includes()方法接收兩個(gè)參數(shù)嘉抓,搜索的內(nèi)容開始搜索的索引,默認(rèn)值為0晕窑,若搜索值在數(shù)組中則返回true否則返回false抑片。

['a', 'b', 'c', 'd'].includes('b');      // true
['a', 'b', 'c', 'd'].includes('b', 1);   // true
['a', 'b', 'c', 'd'].includes('b', 2);   // false

indexOf方法對比,下面方法效果相同:

['a', 'b', 'c', 'd'].indexOf('b') > -1;  // true
['a', 'b', 'c', 'd'].includes('b');      // true 

includes()與indexOf對比:

  • includes相比indexOf更具語義化杨赤,includes返回的是是否存在的具體結(jié)果敞斋,值為布爾值,而indexOf返回的是搜索值的下標(biāo)疾牲。
  • includes相比indexOf更準(zhǔn)確植捎,includes認(rèn)為兩個(gè)NaN相等,而indexOf不會(huì)阳柔。
let a = [1, NaN, 3];
a.indexOf(NaN);     // -1
a.includes(NaN);    // true

另外在判斷+0-0時(shí)焰枢,includesindexOf的返回相同。

[1, +0, 3, 4].includes(-0);   // true
[1, +0, 3, 4].indexOf(-0);    // 1

[參考資料]

1.MDN 索引集合類
2.MDN 數(shù)組對象
3.W3school JavaScript Array 對象

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末舌剂,一起剝皮案震驚了整個(gè)濱河市济锄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌霍转,老刑警劉巖拟淮,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異谴忧,居然都是意外死亡很泊,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進(jìn)店門沾谓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來委造,“玉大人,你說我怎么就攤上這事均驶』枵祝” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵妇穴,是天一觀的道長爬虱。 經(jīng)常有香客問我隶债,道長,這世上最難降的妖魔是什么跑筝? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任死讹,我火速辦了婚禮,結(jié)果婚禮上曲梗,老公的妹妹穿的比我還像新娘赞警。我一直安慰自己,他們只是感情好虏两,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布愧旦。 她就那樣靜靜地躺著,像睡著了一般定罢。 火紅的嫁衣襯著肌膚如雪笤虫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天祖凫,我揣著相機(jī)與錄音琼蚯,去河邊找鬼。 笑死蝙场,一個(gè)胖子當(dāng)著我的面吹牛凌停,可吹牛的內(nèi)容都是我干的粱年。 我是一名探鬼主播售滤,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼台诗!你這毒婦竟也來了完箩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤拉队,失蹤者是張志新(化名)和其女友劉穎弊知,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體粱快,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡秩彤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了事哭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漫雷。...
    茶點(diǎn)故事閱讀 38,018評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鳍咱,靈堂內(nèi)的尸體忽然破棺而出降盹,到底是詐尸還是另有隱情,我是刑警寧澤谤辜,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布蓄坏,位于F島的核電站价捧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏涡戳。R本人自食惡果不足惜结蟋,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望妹蔽。 院中可真熱鬧椎眯,春花似錦、人聲如沸胳岂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乳丰。三九已至掌测,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間产园,已是汗流浹背汞斧。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留什燕,地道東北人粘勒。 一個(gè)月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像屎即,于是被迫代替她去往敵國和親庙睡。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容