數組在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
//數組字面量建立 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());
方法一,建立對象的鍵值惟一性來進行去重:
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]
var arr = [1,2,3,4]; var arr1 = arr.slice(); var arr2 = arr.concat();
注:這裏的複製指的是淺拷貝
這裏的數組指的是全是數字的數組
方法一,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
在不用系統自帶的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));
注:若是數組中有重複數字則排序方法有誤,會把重複數字去掉。
寫完以後發現其實也沒有比冒泡、插入以及快速排序的方法快多少。
一開始我想到一個方法,把兩個數組轉換成字符串,在進行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;
寫這篇文章主要是對本身學習數組作一個總結。若是對上面的問題有更好的解答,歡迎留言告知。