學習筆記——陣列方法整理

Christine發表於2018-01-25

前言:

定義:陣列是值的有序集合。 JS的陣列是無型別的,陣列元素可以是任意型別,並且同一個陣列的不同元素也可能有不同的型別,每一個值叫做元素(陣列元素),每個元素在陣列中有一個位置。陣列在平常的coding中是比較常用的資料格式,尤其式在解析後臺資料時。每個方法我都配有示例,希望能通過示例的解析,讓大家對方法能有更清晰對理解。除此之外,字串和物件的方法也會在過兩天分享,希望能對您有些許幫助,這將是我莫大的榮幸!

一、建立陣列 x=[ ]

let a=["333","999"];        // 直接寫在[ ]中

let aa=new Array(4,8,9);    // 通過例項傳入Array中

let aaa=new Array(5);       // 傳入的5為array的個數

    aaa[0]=6;               // 給aaa的第0個賦值為6

console.log(aaa);           //  [6,,,,,]

console.log(aa);            //  [4,8,9]
複製程式碼

二、 訪問陣列元素 x.[index]

let a=["333","999"];

let b=a[0];              // 訪問陣列的第一個元素

let c=a[a.length-1];     // 訪問陣列的最後一個元素

let f=a["1"]===a[1];     // a["1"]會自動轉為數字1 

console.log(f);          //  true

複製程式碼

當然,如果我們通過以下方式去訪問時,會被解析成連續運算返回最後一個值

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

陣列也是一種特殊的物件,因此我們也可以通過鍵值對的形式去訪問

let arr9 = [];

    arr9.say = 'Hello';

console.log(arr9.say)    // Hello
複製程式碼

三、遍歷陣列 x.forEach(function(item,index,array){})

es6寫法 forEach((item,index)=>{dosomething.....})

let a=["333","999"];

   a.forEach(function (item,index,array) {

           console.log(item,index)

 });
       //333 0  999 1
複製程式碼

四、新增元素到陣列的末尾 x.push(...)

let a=["333","999"];

    a.push("我是新元素","666");  

console.log(a);    //["333","999","我是新元素","666"]

console.log(a.push("我","690"),a.length,a);  //6,["333","666","我是新元素","666","我","690"]

//返回新陣列長度6,會執行一次a.push

複製程式碼

五、在末尾刪除陣列(只能刪除1個) x.pop()

let a=["333","999"];

    a.pop();

console.log(a);            // ["333"];  返回新陣列

console.log( a.pop(),a);   //333 [] 

//會執行一次a.pop(),返回本次被刪除元素
複製程式碼

六、刪除陣列最前面元素 x.shift()

let a=["333","999"];

    a.shift();

console.log(a);            //  ["999"]

console.log( a.shift());   //  "999"

  //返回被刪除元素,不會執行a.shift()
複製程式碼

七、新增到陣列的前面(頭部)x.unshift("...")

let a=["333","999"];

    a.unshift("000","888","777");

console.log(a);            

// ["000","888","777","333","999"]

console.log(a.unshift("111"),a.length,a); 

//["111","000","888","777","333","999"]
  
   //會執行一次a.unshift,返回陣列長度,
複製程式碼

八、找到某個元素在陣列中的索引 indexOf

let a=["333","999"];

let d=a.indexOf("333");   // 通過元素查詢在當前陣列的索引值

console.log(d);           // 0

let e=a.indexOf("654");   // 如果查不到返回-1

console.log(e);           // -1
複製程式碼

九、複製陣列 slice() , Array.from() [...]

let a=[1,2,8]; 

let newArray=a.slice();

console.log(newArray);   //第一種方法  [1,2,8]  

-----------------------------------

let newArray2=Array.from(a);

console.log(newArray2);  //第二種方法 [1,2,8]

------------------------------------

let newArray3=[...a];

console.log(newArray3);  //第三種方法 [1,2,8]

複製程式碼

十、清空陣列

// 兩種方法都可以實現,但第二種比較優雅

let arr=[1,2,3,3,4,5];

    arr=[];

console.log(arr)     //  []

------------------------------------

let arr=[888,99];

    arr.length=0;

console.log(arr)     //  []
複製程式碼

十一、合併陣列

let arr=[1];

let arr2=[2];

let arr3=[3];

let arr4=arr.concat(arr2,arr3) 

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

---------------------------------------
// 下面這個方法也可以實現,但只能合併兩個陣列

let arr1=[1,2,3];

let arr2=[4,5,6];

    arr1.push.apply(arr1,arr2);
   
console.log(arr1);   // [1, 2, 3, 4, 5, 6]

-------------------------------------
// ES6的陣列合並:

const arr1 = ['a', 'b'];
const arr2 = ['c'];
const arr3 = ['d', 'e'];

[...arr1, ...arr2, ...arr3];    // [ 'a', 'b', 'c', 'd', 'e' ]

複製程式碼

十二、在陣列中找到最大值和最小值

//方法1
let array1 = [1,2,3,4];

let array2 = Math.max.apply(null,array1);  // 最大值

let array3 = Math.min.apply(null,array1);  // 最小值

console.log(array2,array3);                // 4 ,1

--------------------------------------------------

//方法2
let array4 =Math.max(...array1);         // 最大值

let array5 =Math.min(...array1);         // 最小值

console.log(array4,array5);              // 4 ,1
複製程式碼

十三、判斷是不是陣列

// 在javascript中,如何判斷一個變數是否是陣列

(1)Array.isArray()方法

    var a = [0, 1, 2];

    console.log(Array.isArray(a));   // true

(2)typeof  toString 方法
複製程式碼

由於低版本的IE不支援ES5,如需要相容,用typeof,我們都知道,陣列是特殊的物件,所以陣列的typeof結果也是object,而因為null的結果也是object,所以需要加判斷是 object同時排除null、排除純物件,先判斷a是不是object,並且a!==null, 並且toString.call判斷a等於 [object Array]

let a = [0, 1, 2];  

console.log( typeof a ==='object' &&  a !==null  &&  Object.prototype.toString.call(a) ==='[object Array]');   //  true
複製程式碼

十四、陣列與其他值的運算(使用"+"會自動轉為string,"-"會自動轉為number)

// 陣列和任何值相加都會將陣列轉換成字串再進行拼接

console.log([1,2,3] + 6) ;       // "1,2,36"

console.log([1,2,3] + {}) ;      // "1,2,3[object Object]"

console.log([1,2,3] + [1,2,3]); // "1,2,31,2,3"
  
如果陣列只有一個值,那麼當這個陣列和其他值相減相乘等時會被轉換為數字,如果為空會被轉換為0
    
console.log([5] - 2)          // 3
複製程式碼

十五、陣列去重

// ES6新增的Set資料結構,類似於陣列,但是裡面的元素都是唯一的,其建構函式可以接受一個陣列作為引數

let arr1=[1,2,1,2,6,3,5,69,66,7,2,1,4,3,6,8,9663,8]

let set = new Set(arr1);  

console.log(set)       //  {1,2,6,3,5,69,66,7,4,8,9663,8]

// ES6中Array新增了一個靜態方法from,可以把類似陣列的物件轉換為陣列

let arr=[1,2,1,2,6,3,5,69,66,7,2,1,4,3,6,8,9663,8]

console.log(Array.from( new Set(arr)))  // {1,2,6,3,5,69,66,7,4,8,9663,8]
 
//函式去重:  

function removeRepeatArray(arr){
        return Array.from(new Set(arr))
}
console.log(removeRepeatArray([1,5,9,8,6,2,5,1,2,5,8,65,3,5,5,2,2,5]))
    //  [1, 5, 9, 8, 6, 2, 65, 3]
複製程式碼

十六、將陣列順序打亂

function upsetArr(arr){
    return arr.sort(function(){ return Math.random() - 0.5});
}
複製程式碼

解析:沿用原sort的a-b的方法,先生成一個隨機數,然後將其與隨機數進行 比較,如果Math.random() - 0.5是true,則返回前者,否則比較下一個

十七 實現將陣列中數字求和,字母忽略。

let = ["a",3,4,5,9,"d"];
function sum (arr){
    let a=0;
    for(let i=0;i<arr.length;i++){
        if(typeof arr[i]==="number"){
            a+=arr[i]
        }
    }
    return a; 
}

sum(arr)  //21
複製程式碼

通過迴圈遍歷判斷陣列中的每個值是否是數字,如果是的賦值到變數上進行加法計算

十八、deletesplice刪除陣列內指定的某個值。

使用delete刪除陣列內的制定索引的值後,直接改的是原陣列,而且刪除值的位置仍然保留,為undefined

let arr=[1,2,3,45,5,2];

    delete arr[0]

console.log(arr,arr[0]).   // [empty,2,3,45,5],undefined
複製程式碼

如果要徹底刪除,可以使用splice()方法 splice(開始位置,刪除個數,新增的值),如果沒有第三個值,可以只傳前兩個值

兩個值的示例:

let arr=[1,2,3,45,5,2];

    arr.splice(0,1)

console.log(arr)    //  [2, 3, 45, 5, 2]
複製程式碼

三個值的示例:

let arr=[1,2,3,45,5,2];

    arr.splice(0,1,100)

console.log(arr)     //  [100 ,2, 3, 45, 5, 2]
複製程式碼

十九、slice()擷取陣列,可選擇開始位置和結束位置

slice()接收兩個引數,第一個是開始位置,第二個是結束位置

let arr=[1,2,3,45,5,2];

    arr.slice(0,4)

console.log(arr). //  [1, 2, 3, 45]
複製程式碼

如果slice()括號中不傳引數,將會全部擷取

let arr=[1,2,3,45,5,2];

    arr.slice()

console.log(arr).  //  [1, 2, 3, 45, 5, 2]
複製程式碼

二十、顛倒陣列的順序,也稱陣列的反轉

let arr=[1,2,3,45,5,2];

    arr.reverse()

console.log(arr)   // [2, 5, 45, 3, 2, 1]
複製程式碼

二十一、join()將陣列以括號中的值分割成字串(不會改變原陣列)

let arr=[1,2,3,45,5,2];

console.log(arr.join("_”));  //  "1_2_3_45_5_2"

console.log(arr);   //  [1, 2, 3, 45, 5, 2]
複製程式碼

二十二、sort()排序,將陣列中的值進行排序,從大到小或從小到大(會改變原本的陣列)

sort原本的排序功能只能識別到個位數做比較,所以擴充套件使用以下方法:(排序方法有很多,這是最傳統,也是使用頻率較多的,其他的方法不再贅述)

let arr=[1,2,3,45,5,2];

    arr.sort(function(a,b){
        return a-b
    })   
   //  [1, 2, 2, 3, 5, 45]

檢視此時的arr陣列:
    console.log(arr)  //   [1, 2, 2, 3, 5, 45]

    arr.sort(function(a,b){
        return b-a
    })
  //  [45, 5, 3, 2, 2, 1]

檢視此時的arr陣列:
    console.log(arr)  //   [45, 5, 3, 2, 2, 1]
複製程式碼

當然我們有時是不可以改變原陣列的,那麼可以試試下面的方法將需要的內容拷貝出來即可:

let arr=[1,3,6,8,45,34,90,122,9,0];

let array=arr.slice();

    array.push(34)

console.log(arr,array)

// [1,3,6,8,45,34,90,122,9,0],[1,3,6,8,45,34,90,122,9,0,34] 
複製程式碼

二十三、 Array.protype.slice.call(arr,n,m) 擷取陣列,返回新陣列(不會改變原陣列)

引數(前不包,後包含):

arr:擷取的陣列 n:擷取開始位置 m:擷取結束位置

今天有學到一個新的方法,推薦給大家,陣列中的slice.call() 方法,返回一個擷取的新陣列,(前不包,後包含)接下來我們帶入一個?來現身說法:

1.向後擷取,第二個引數2是指給定擷取的位置,刪除當前位置前的元素,返回包含第二個引數之後的陣列副本。

let arr = [1,2,5,3,6];
console.log(Array.prototype.slice.call(arr,2)) // [5,3,6]

2.向前擷取,首先找到擷取位置為2,然後找到擷取截止位置4,返回從首位數第二個引數開始,截止到第四個位置的陣列副本:
let arr = [1,2,5,3,6];
console.log(Array.prototype.slice.call(arr,2,4)) // [5,3]
複製程式碼

陣列中的迭代方法filter(), every(),forEach(),map(),some()

filter():對陣列中的每一項執行給定函式,返回該函式會返回true 的項組成的陣列。

every():對陣列中的每一項執行給定函式,如果該函式對每一項都返回true,則返回true

forEach():對陣列中的每一項執行給定函式。這個方法沒有返回值。

map():對陣列中的每一項執行給定函式,返回每次函式呼叫的結果組成的陣列。

some():對陣列中的每一項執行給定函式,如果該函式對任一項返回true,則返回true.

一、陣列迭代方法之filter()

filter返回的是一個符合某種條件的陣列,並返回,不會更改原陣列)

let arr=[1,3,6,8,45,34,90,122,9,0];

let array = arr.filter(function(element){

        return element>10
    })
console.log(array)

//篩選陣列中大於10的值, [45, 34, 90, 122]

//檢視原陣列,並沒有改變

console.log(arr)    //  [1,3,6,8,45,34,90,122,9,0]
複製程式碼

還可以直接過濾假值:借鑑於傳送門

const compact = arr=> arr.filter(Boolean)
compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34])    // [1, 2, 3, "a", "s", 34] 
複製程式碼

關於這個過濾假植,在很多工具庫都有自己的方法進行處理,下面我們就某庫中的方法和filter做一個比較,看具體執行效率(認真臉)。

// 方法本身
function lodashCompact(array) {
  var index = -1,
    length = array == null ? 0 : array.length,
    resIndex = 0,
    result = [];

  console.time("lodashCompact");
  while (++index < length) {
    var value = array[index];
    if (value) {
      result[resIndex++] = value
    }
  }
  console.timeEnd("lodashCompact");
  return result;
}
// lodash 方法實現
function test() {
    lodashCompact(arr);
}
// filter 方法實現
function test2() {
    console.time("filter用時共計")
    const compacts = arr => arr.filter(Boolean)
    console.timeEnd("filter用時共計")
}

複製程式碼

學習筆記——陣列方法整理

上面計算的是純執行時間,filter 遠遠超越約7.6倍,推薦使用filter

二、陣列迭代方法之every()

(主要是用於判斷一個素組中的值是否符合某個標準。必須是每個值都符合才會返回true。否則返回false

let arr = [1,2,3,4,5,4,3,2,1]; 

let everyResult = arr.every(function(item, index, array){ 
    return (item > 2); 
}); 

//判斷陣列中所有的值是否都大於2,如果都大於2,返回true,反之返回false.

console.log(everyResult)     //false 
複製程式碼

三、陣列迭代方法之forEach()

(陣列的迴圈遍歷,對陣列中的每一項執行給定函式。這個方法沒有返回值。)

let arr=[1,3,6,8,45,34,90,122,9,0];

    arr.forEach(function(item,index,array){
        console.log(item,index,array)
    })
/*
 0 1 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 1 3 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 2 6 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 3 8 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 4 45 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 5 34 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 6 90 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 7 122 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 8 9 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 9 0 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
*/
複製程式碼

四、陣列迭代方法之map()

(陣列的迴圈遍歷,對陣列中的每一項執行給定函式,返回每次函式呼叫的結果組成的陣列。)

let arr=[1,3,6,8,45,34,90,122,9,0];

    arr.map(function(item,index,array){
        console.log(index,item,array)
    })
 /*
 0 1 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 1 3 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 2 6 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 3 8 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 4 45 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 5 34 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 6 90 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 7 122 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 8 9 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 9 0 (10) [1, 3, 6, 8, 45, 34, 90, 122, 9, 0]
 */
複製程式碼

五、陣列迭代方法之some()

(對陣列中的每一項執行給定函式,如果該函式對任一項返回true,則返回true)

let numbers = [1,2,3,4,5,4,3,2,1]; 

let someResult = numbers.some(function(item, index, array){ 
    return (item > 2); 
}); 

//只要有一個返回true,則返回true

console.log(someResult); // true
複製程式碼

歸併:迭代陣列中的所有值,返回一個按條件計算的最終值。

reduce:

let values = [1,2,3,4,5]; 

let sum = reduce(function(prev, cur, index, array){ 
    return prev + cur; 
}); 

//第一次執行回撥函式,prev 是1,cur 是2。第二次,prev 是3(1 加2 的結果),cur 是3(陣列的第三項)。這個過程會持續到把陣列中的每一項都訪問一遍,最後返回結果。 
//通過迴圈遍歷,返回陣列中所有值的總和  15
複製程式碼

reduceRight:

let values = [1,2,3,4,5]; 

let sum = reduceRight(function(prev, cur, index, array){ 
    return prev + cur; 
}); 

//第一次執行回撥函式,prev 是5,cur 是4。第二次,prev 是9(5加4 的結果),cur 是3(陣列的第三項)。這個過程會持續到把陣列中的每一項都訪問一遍,最後返回結果。 
//通過迴圈遍歷,返回陣列中所有值的總和  15


複製程式碼

ES6 中的 find :找到陣列中第一個符合條件到值。

1.當在陣列中匹配到符合條件的元素,則返回符合條件的元素,之後的值不會再呼叫執行函式;

2.如果沒有符合條件的元素返回 undefined;

注意: find() 對於空陣列,函式是不會執行的。

注意: find() 並沒有改變陣列的原始值。


 var arr = [1,2,3,4,5,6,7];
 var ar = arr.find((elem)=>{
    return elem>5
 })  // 6
複製程式碼

ES6 中的 Array.from: 方法用於將兩類物件轉為真正的陣列

Array.from 方法用於將兩類物件轉為真正的陣列:類似陣列的物件(array-like object)和可遍歷(iterable)的物件(包括 ES6 新增的資料結構 Set 和 Map)。

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會返回一個一模一樣的新陣列。

Array.from([1, 2, 3]);  // [1, 2, 3]
複製程式碼

Array.from還可以接受第二個引數,作用類似於陣列的map方法,用來對每個元素進行處理,將處理後的值放入返回的陣列。

Array.from(arrayLike, x => x * x);
// 等同於
Array.from(arrayLike).map(x => x * x);

// 
Array.from([1, 2, 3], (x) => x * x);   // [1, 4, 9]

複製程式碼

下面的例子將陣列中布林值為false的成員轉為0。

Array.from([1, , 2, , 3], (n) => n || 0)   // [1, 0, 2, 0, 3]

複製程式碼

另一個例子是返回各種資料的型別。

function typesOf () {
  return Array.from(arguments, value => typeof value);
}
typesOf(null, [], NaN);    // ['object', 'object', 'number']

複製程式碼

ES6中的 Array.prototype.flat() 用於將巢狀的陣列“拉平”,變成一維的陣列。

該方法返回一個新陣列,對原資料沒有影響。

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

// 上面程式碼中,原陣列的成員裡面有一個陣列,flat()方法將子陣列的成員取出來,新增在原來的位置。
複製程式碼

flat()預設只會“拉平”一層,如果想要“拉平”多層的巢狀陣列,可以將flat()方法的引數寫成一個整數,表示想要拉平的層數,預設為1。

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

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

複製程式碼

上面程式碼中,flat()的引數為2,表示要“拉平”兩層的巢狀陣列。如果不管有多少層巢狀,都要轉成一維陣列,可以用Infinity關鍵字作為引數。

[1, [2, [3]]].flat(Infinity);   // [1, 2, 3]

複製程式碼

如果原陣列有空位,flat()方法會跳過空位。

[1, 2, , 4, 5].flat();  // [1, 2, 4, 5]

複製程式碼

ES6中的空值

ES5 對空位的處理,已經很不一致了,大多數情況下會忽略空位。

forEach(), filter(), reduce(), every()some()都會跳過空位。

map()會跳過空位,但會保留這個值

join()toString()會將空位視為undefined,而undefinednull會被處理成空字串。

// forEach方法
[,'a'].forEach((x,i) => console.log(i)); // 1

// filter方法
['a',,'b'].filter(x => true) // ['a','b']

// every方法
[,'a'].every(x => x==='a') // true

// reduce方法
[1,,2].reduce((x,y) => x+y) // 3

// some方法
[,'a'].some(x => x !== 'a') // false

// map方法
[,'a'].map(x => 1) // [,1]

// join方法
[,'a',undefined,null].join('#') // "#a##"

// toString方法
[,'a',undefined,null].toString() // ",a,,"

複製程式碼

ES6 則是明確將空位轉為undefined。


ES6部分引用:阮一峰老師的ES6

    作者:晴天de雨滴    
    出處:https://juejin.im/post/5a125827518825293b4fea8a
    版權所有,歡迎保留原文連結進行轉載:) 
複製程式碼

如果你對我對文章感興趣或者有些建議想說給我聽?,也可以新增一下微信哦!

學習筆記——陣列方法整理
如果親感覺我的文章還不錯的話,可以一下新增關注哦!

-----再或者感覺我的文章對您有所幫助,可以掃描二維碼打賞一下我呦!這樣我會更有動力給大家提供更優質的文章哦! 謝謝您!!!

學習筆記——陣列方法整理

最後:
        祝各位工作順利!
                        -小菜鳥Christine
複製程式碼

相關文章