javascript中數組的回顧

數組在javascript中使用度很是頻繁,我總結了一些在數組中很常見的問題。javascript

關於數組中的方法很是多,我總結了一張表來大體瞭解數組中的方法java

Array中的方法 含義 改變原數組 返回值 ES6新增
concat 合併兩個或多個數組 false 新數組 false
copyWithin 淺複製數組的一部分到同一數組中的另外一個位置 true 改變後的數組 true
entries 返回數組迭代器對象,該對象包含數組中每一個索引的鍵/值對 false 數組迭代器 true
every 測試數組的全部元素是否都經過了指定函數的測試 false 布爾值,true/false false
fill 用一個固定值填充一個數組中從起始索引到終止索引內的所有元素 true 改變後的數組 true
filter 建立一個新數組, 其包含經過所提供函數實現的測試的全部元素 false 新數組 false
find 返回數組中知足提供的測試函數的第一個元素的值。不然返回undefined false javascript語言類型 true
findIndex 返回數組中知足提供的測試函數的第一個元素的索引。不然返回-1 false 數組索引 true
forEach 遍歷數組 false undefined false
includes 判斷一個數組是否包含一個指定的值 false 布爾值,true/false true
indexOf 返回在數組中能夠找到一個給定元素的第一個索引,若是不存在,則返回-1 false 數組索引 false
join 將數組(或一個類數組對象)的全部元素鏈接到一個字符串中 false 字符串 false
keys Array迭代器,它包含數組中每一個索引的鍵 false 數組迭代器 true
lastIndexOf 返回指定元素在數組中的最後一個的索引,若是不存在則返回 -1 false 數組索引 false
map 遍歷數組 false 新數組 false
pop 從數組中刪除最後一個元素,並返回該元素的值 true 數組元素 false
push 將一個或多個元素添加到數組的末尾,並返回新數組的長度 true 數組長度 false
reduce 對累加器和數組中的每一個元素(從左到右)應用一個函數,將其減小爲單個值 false 函數返回值 false
reduceRight reduce執行方向相反,從右到左 false 函數返回值 false
reverse 將數組中元素的位置顛倒 true 改變後的數組 false
shift 從數組中刪除第一個元素,並返回該元素的值 true 數組元素 false
slice 可從已有的數組中返回選定的元素 false 新數組 false
some 測試數組中的某些元素是否經過由提供的函數實現的測試 false 布爾值,true/false false
sort 在適當的位置對數組的元素進行排序 true 一個新數組 false
splice 刪除現有元素和/或添加新元素來更改一個數組的內容 true 刪除的元素數組 false
toLocaleString 返回一個字符串表示數組中的元素 false 字符串 false
toString 返回一個字符串,表示指定的數組及其元素 false 字符串 false
unshift 將一個或多個元素添加到數組的開頭 true 數組長度 false
values 一個數組迭代器對象,該對象包含數組每一個索引的值 false 數組迭代器 true

從這個表中咱們要當心幾個方法,reverse和sort會改變原數組,並返回改變的新數組,push和unshift方法返回的是數組長度而不是數組,forEach方法返回的是undefined不是數組。數組

此外,我還需提一下slice和splice這兩個方法,說實話這兩個方法看起來很像,容易讓人搞混,最關鍵的是用到的頻率還蠻高的,這兩個方法就像字符串中substr和substring這兩個老兄弟,閒着沒事就喜歡去迷惑別人,本人就曾深深的被這兩個方法傷害過。app

slice接受兩個參數start和end,表明須要截取的數組的開始序號和結束序號。函數

var arr = [4,3,5,8,9,6];
arr.slice(0)    // [4,3,5,8,9,6],end能夠省略,默認爲數組長度
arr.slice(0,4)   //[4,3,5,8]
arr.slice(-1);   //[6],  start爲負數表明從數組截取的開始序號從尾部算起
arr.slice(0,-1);  //[4,3,5,8,9]   end爲負數表示結束序號從尾部算起
arr.slice(2,0);   //[]
arr.slice(-1,-1);   //[]  若是start和end符號相同,end必定大於start,不然返回的會是[]

splice的參數爲index,deleteCount和...items,index表示須要刪除或添加原數時的位置,負數表示從尾部算起,deleteCount表示要刪除的元素,0表示不刪除。其中items表示添加的元素個數。學習

var arr = [4,3,5,8,9,6];
arr.splice(0,0)      //返回[], arr=[4,3,5,8,9,6];
arr.splice(0,2)      //返回[4,3], arr=[5,8,9,6];
arr.splice(0,2,3,4)  //返回[5,8], arr=[3,4,9,6];

splice不論是添加仍是刪除元素,返回的都是刪除元素的列表,splice是先作刪除操做,後添加測試

var arr = [4,3,5];
arr.splice(3,1,8,9);     //返回[], arr= [4, 3, 5, 8, 9];
//若是index大於數組長度,那麼splice不會刪除元素

注意:雖然slice和splice都返回一個新的數組,可是slice不會改變原數組,splice會改變原數組,這個區別很是關鍵。this

最後在加一些常常會問到的數組問題。code

1.建立數組

//數組字面量建立
var arr = [1,2];

//Array構造器建立;
var arr = Array(1,2);     //[1,2]  能夠用new操做符,也能夠不用
//Array構造器有個侷限性,不能建立只有單個數字的數組
var arr = Array(10)       //建立的是一個長度爲10的空數組,並非[10]
//若是傳入的不是Number類型的數字,那麼沒有任何問題
var arr = Array('10')     //['10']

//此時若是要建立只有單個數字的數組,能夠用Array.of方法
var arr = Array.of(10)    //[10]
var arr = Array.of(1,2)   //[1,2]

//Array.from( items [ , mapfn [ , thisArg ] ] )
//items是個可迭代對象,mapfn是遍歷該迭代對象的function,thisArg是mapfn中的this對象
var arr = Array.from([1,2,3])    //[1,2,3]

Array.from是很是有用的建立數組方法,能把字符串轉化爲數組,Map,Set也能轉成數組。對象

Array.from('abc')        //['a','b','c'];
Array.from(new Set([1,2,3]))  //[1,2,3],固然這個例子毫無心義
Array.from(new Map([[1,2],[3,4]]))  //[[1,2],[3,4]]

咱們知道用Array構造器建立的數組是個空數組,map,forEach方法並不能遍歷這個數組。

var arr = Array(10);
arr.forEach((item,index) => console.log(index))   //不會有輸出
//map,forEach循環判斷的是該對象上有沒有對應的屬性
arr.hasOwnProperty(0)            //false,以hasOwnProperty爲判斷標準
//Array.from中的mapfn方法是以迭代方式來判斷的,所以
Array.from(arr,(item,index)=>console.log(index))   //0,1,2,3,4,5,6,7,8,9

因爲這個緣由,咱們能夠快速對數組初始化,好比建立一個0到99的數組

Array.from(Array(100),(item,index)=>index);
//固然,若是你用到上表中Array的keys方法那更快捷
Array.from(Array(100).keys());

2.數組去重

方法一,建立對象的鍵值惟一性來進行去重:

var arr = [1,2,3,1,3,5,3,2];
var _arr = [];
var obj = {};
arr.forEach(item => {
    if(!obj[item]){
       _arr.push(item);
       obj[item] = true;
    }
})
arr = _arr;

方法二,結合Set的鍵值惟一性以及Array.from方法能夠快速數組去重:

var arr = Array.from(new Set([1,2,3,1,3,5,3,2]))   //[1,2,3,5]

3.快速複製一個數組

var arr = [1,2,3,4];
var arr1 = arr.slice();
var arr2 = arr.concat();
注:這裏的複製指的是淺拷貝

4.求數組最大值,最小值

這裏的數組指的是全是數字的數組

方法一,sort排序後取值

var arr = [1,4,6,2,33,19,6,9];
var maxvalue = arr.sort((a,b) => b>a )[0]
var minvalue = arr.sort((a,b) => a>b )[0]

方法二,Math的max和min方法調用

var arr = [1,4,6,2,33,19,6,9];
var maxvalue = Math.max.apply(null,arr);   //33
var minvalue = Math.min.apply(null,arr);   //1

5.數組排序

在不用系統自帶的sort的狀況下對數組排序有不少方法,好比冒泡、插入以及快速排序等。但我總以爲這些排序方法仍是過於複雜,有沒有更快以及更方便的排序,我思考了很久,後來先想到了能夠用數組的序號進行排序。原理是把數組1中的值變成數組2中的序號:

var arr = [3,4,6,2,8,7,5],
    arr2 = [];
arr.forEach(item => arr2[item] = item);
arr = [];
arr2.forEach(item => arr.push(item));

寫完以後本身感受美滋滋,可以後發現若是數組中有負數,不就都玩完了嗎。因而趕忙改:

var arr = [3,-4,6,-2,-8,7,5],
    parr = [];
    narr = [];
arr.forEach(item => item>=0?parr[item] = item:narr[-item] = item);
arr = [];
parr.forEach(item => arr.push(item));
narr.forEach(item => arr.unshift(item));
注:若是數組中有重複數字則排序方法有誤,會把重複數字去掉。

寫完以後發現其實也沒有比冒泡、插入以及快速排序的方法快多少。

6.求一個整數數組是否包含另外一個整數數組

一開始我想到一個方法,把兩個數組轉換成字符串,在進行includes或者indexOf判斷就能夠了,後來我發現了問題:

var a = [2,4,8,6,12,67,9];
var b = [8,6,12];
a.join(',').includes(b.join(','));   //true;  這是能夠的

var b = [8,6,1]
a.join(',').includes(b.join(','));   //true;  這竟然也能夠,顯然有問題

//因而改爲
a.join(',').includes(','+b.join(',')+',');  //false;

//後來我又發現若是b數組在a數組的開頭和結尾都會有問題,因而又改爲以下:

(','+a.join(',')+',').includes(','+b.join(',')+',');  //false;

寫這篇文章主要是對本身學習數組作一個總結。若是對上面的問題有更好的解答,歡迎留言告知。

相關文章
相關標籤/搜索