數組是我們使用十分頻繁的一種數據類型,是否能夠熟練掌握數組的高級方法,將會直接影響我們的工作效率。在開始本文之前,小伙伴們可以先看下之前關于數組遍歷的文章,里面的內容在本文中將不會再贅述:
一.過濾方法 filter
**filter()**
方法創建一個新數組, 其包含通過所提供函數實現的測試的所有元素。 、
var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
1.1 參數
-
callback
用來測試數組的每個元素的函數。返回
true
表示該元素通過測試,保留該元素,false
則不保留。它接受以下三個參數:element
數組中當前正在處理的元素。index
可選正在處理的元素在數組中的索引。array
可選調用了filter
的數組本身。 -
thisArg
可選執行
callback
時,用于this
的值。
1.2 返回值
一個新的、由通過測試的元素組成的數組,如果沒有任何數組元素通過測試,則返回空數組。
-
filter
不會改變原數組,它返回過濾后的新數組。
1.3 描述
filter
為數組中的每個元素調用一次 callback
函數,并利用所有使得 callback
返回 true 或等價于 true 的值的元素創建一個新數組。callback
只會在已經賦值的索引上被調用,對于那些已經被刪除或者從未被賦值的索引不會被調用。那些沒有通過 callback
測試的元素會被跳過,不會被包含在新數組中。
callback
被調用時傳入三個參數:
- 元素的值
- 元素的索引
- 被遍歷的數組本身
如果為 filter
提供一個 thisArg
參數,則它會被作為 callback
被調用時的 this
值。否則,callback
的 this
值在非嚴格模式下將是全局對象,嚴格模式下為 undefined
。callback
函數最終觀察到的 this
值是根據通常函數所看到的 "this"的規則確定的。
1.4 例子:數組大于5的人
// filter案例:選出數組中大于五的數
let arr = [5, 6, 8, 10, 24];
let bigThanEightArr = arr.filter((item, index, arr) => {
// console.log(item, index, arr);
return item > 6
}, this);
console.log(bigThanEightArr); //[8,10,24]
上面的代碼是 filter 方法的使用方式,filter 接收兩個參數,并最終返回一個新的數組。filter 的兩個參數分別是:
第一個是回調函數。回調函數有三個參數分別當前的元素、當前元素的索引、原數組,可以在回調函數中進行一些操作,從而判斷是否要保留這個元素,如果要保留,則回調函數需要返回 true ,反之則返回 false
在上面的代碼中,只要當前的元素大于 5 ,item > 5 就會返回 true ,從而將該值保留,因此將原數組過濾后的新數組是 [6, 8, 9]
第二個參數用于指定回調函數執行時,this 的指向。上面的代碼中并沒有設置該參數,因此在回調中打印 this 時,其指向為 window 對象
二.加工方法map
**map()**
方法創建一個新數組,其結果是該數組中的每個元素是調用一次提供的函數后的返回值。
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array
}[, thisArg])
2.1 參數
- callback生成新數組元素的函數,使用三個參數:
-
currentValue
:callback數組中正在處理的當前元素。 -
index
可選:callback
數組中正在處理的當前元素的索引。 -
array
可選:map
方法調用的數組。 -
thisArg
可選:執行callback
函數時值被用作this
。
2.2 返回值
一個由原數組每個元素執行回調函數的結果組成的新數組。
2.3 案例:map案例:將原數組每個元素都乘以2
// map案例:將原數組每個元素都乘以2
let doubleArr = arr.map((item, index, arr) => item * 2);
console.log(doubleArr); //[10, 12, 16, 20, 48]
2.4 以下代碼使用一個包含對象的數組來重新創建一個格式化后的數組。
var kvArray = [{key: 1, value: 10},
{key: 2, value: 20},
{key: 3, value: 30}];
var reformattedArray = kvArray.map(function(obj) {
var rObj = {};
rObj[obj.key] = obj.value;
return rObj;
});
// reformattedArray 數組為: [{1: 10}, {2: 20}, {3: 30}],
// kvArray 數組未被修改:
// [{key: 1, value: 10},
// {key: 2, value: 20},
// {key: 3, value: 30}]
三.reduce
3.1 參數
callback
執行數組中每個值 (如果沒有提供 initialValue則第一個值除外
)的函數,包含四個參數:
accumulator
-
currentValue
數組中正在處理的元素。
-
index
可選數組中正在處理的當前元素的索引。 如果提供了
initialValue
,則起始索引號為0,否則從索引1起始。 -
array
可選調用
reduce()
的數組
initialValue
可選
作為第一次調用 callback
函數時的第一個參數的值。 如果沒有提供初始值,則將使用數組中的第一個元素。 在沒有初始值的空數組上調用 reduce 將報錯。
3.2 返回值
函數累計處理的結果
3.3 描述
reduce
為數組中的每一個元素依次執行callback
函數,不包括數組中被刪除或從未被賦值的元素,接受四個參數:
accumulator 累計器
currentValue 當前值
currentIndex 當前索引
array 數組
回調函數第一次執行時,accumulator
和currentValue
的取值有兩種情況:
- ==如果調用
reduce()
時提供了initialValue
,accumulator
取值為initialValue
,currentValue
取數組中的第一個值;== - ==如果沒有提供
initialValue
,那么accumulator
取數組中的第一個值,currentValue
取數組中的第二個值。==
注意:如果沒有提供
initialValue
,reduce 會從索引1的地方開始執行 callback 方法,跳過第一個索引。如果提供initialValue
,從索引0開始。
如果數組為空且沒有提供initialValue
,會拋出TypeError
(無論位置如何)并且沒有提供initialValue
, 或者有提供initialValue
但是數組為空,那么此唯一值將被返回并且callback
不會被執行。
3.4 reduce是如何運行的?
假如運行下段reduce()
代碼:
[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array){
return accumulator + currentValue;
});
callback 被調用四次,每次調用的參數和返回值如下表:
callback |
accumulator |
currentValue |
currentIndex |
array |
return value |
---|---|---|---|---|---|
first call | 0 |
1 |
1 |
[0, 1, 2, 3, 4] |
1 |
second call | 1 |
2 |
2 |
[0, 1, 2, 3, 4] |
3 |
third call | 3 |
3 |
3 |
[0, 1, 2, 3, 4] |
6 |
fourth call | 6 |
4 |
4 |
[0, 1, 2, 3, 4] |
10 |
由reduce
返回的值將是最后一次回調返回值(10)。
你還可以使用箭頭函數來代替完整的函數。 下面的代碼將產生與上面的代碼相同的輸出:
[0, 1, 2, 3, 4].reduce((prev, curr) => prev + curr );
如果你打算提供一個初始值作為reduce()
方法的第二個參數,以下是運行過程及結果:
[0, 1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => {
return accumulator + currentValue
}, 10)
callback |
accumulator |
currentValue |
currentIndex |
array |
return value |
---|---|---|---|---|---|
first call | 10 |
0 |
0 |
[0, 1, 2, 3, 4] |
10 |
second call | 10 |
1 |
1 |
[0, 1, 2, 3, 4] |
11 |
third call | 11 |
2 |
2 |
[0, 1, 2, 3, 4] |
13 |
fourth call | 13 |
3 |
3 |
[0, 1, 2, 3, 4] |
16 |
fifth call | 16 |
4 |
4 |
[0, 1, 2, 3, 4] |
20 |
這種情況下reduce()
返回的值是20
。
3.4 reduce練習
3.4.1沒有 有原始參數
// 1.reduce沒有原始參數
let arr = [10, 15, 8, 6, 11, false, 'hello'];
let newArr = arr.reduce((previousValue, currentValue, index, arr) => {
console.log(previousValue, currentValue, index, arr);
return previousValue = previousValue + currentValue;
})
console.log(newArr); //50hello
3.4.2 有原始參數
// 2.reduce有原始參數
let newArr2 = arr.reduce((previousValue, currentValue, index, arr) => {
return previousValue += currentValue;
}, 10);
console.log(newArr2); //60hello
3.4.3 累加對象數組里的值
要累加對象數組中包含的值,必須提供初始值,以便各個item正確通過你的函數。
var initialValue = 0;
var sum = [{x: 1}, {x:2}, {x:3}].reduce(
(accumulator, currentValue) => accumulator + currentValue.x
,initialValue
);
console.log(sum) // logs 6
3.4.4 將二維數組轉化為一維
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(
function(a, b) {
return a.concat(b);
},
[]
);
// flattened is [0, 1, 2, 3, 4, 5]
四.查找數組的元素(find)
**find()**
方法返回數組中滿足提供的測試函數的第一個元素的值。否則返回 undefined
4.1語法
arr.find(callback[, thisArg])
4.2 參數
-
callback
在數組每一項上執行的函數,接收 3 個參數:
element
當前遍歷到的元素。index
可選當前遍歷到的索引。array
可選數組本身。 -
thisArg
可選執行回調時用作
this
的對象。
4.3 返回值
數組中第一個滿足所提供測試函數的元素的值,否則返回 undefined
。
4.4 描述
find
方法對數組中的每一項元素執行一次 callback
函數,直至有一個 callback 返回 true
。當找到了這樣一個元素后,該方法會立即返回這個元素的值,否則返回 undefined
。注意 callback
函數會為數組中的每個索引調用即從 0
到 length - 1
,而不僅僅是那些被賦值的索引,這意味著對于稀疏數組來說,該方法的效率要低于那些只遍歷有值的索引的方法。
callback
函數帶有3個參數:當前元素的值、當前元素的索引,以及數組本身。
如果提供了 thisArg
參數,那么它將作為每次 callback
函數執行時的this
,如果未提供,則使用 undefined
。
find
方法不會改變數組。
在第一次調用 callback
函數時會確定元素的索引范圍,因此在 find
方法開始執行之后添加到數組的新元素將不會被 callback
函數訪問到。如果數組中一個尚未被callback
函數訪問到的元素的值被callback
函數所改變,那么當callback
函數訪問到它時,它的值是將是根據它在數組中的索引所訪問到的當前值。被刪除的元素仍舊會被訪問到,但是其值已經是undefined了。
4.5 案例
let arr = [10, 5, 6, 80, 12];
let element = arr.find((currentValue, index, arr) => {
return currentValue > 70
})
console.log(element); //80
五. 查找數組元素的索引(findIndex)
indIndex()方法返回數組中滿足提供的測試函數的第一個元素的索引。若沒有找到對應元素則返回-1。
5.1語法
arr.findIndex(callback[, thisArg])
5.2參數
-
callback
針對數組中的每個元素, 都會執行該回調函數, 執行時會自動傳入下面三個參數:
element
當前元素。index
當前元素的索引。array
調用findIndex
的數組。 -
thisArg
可選。執行
callback
時作為this
對象的值.
5.3 返回值
數組中通過提供測試函數的第一個元素的索引。否則,返回-1
5.4 描述
findIndex
方法對數組中的每個數組索引0..length-1
(包括)執行一次callback
函數,直到找到一個callback
函數返回真實值(強制為true
)的值。如果找到這樣的元素,findIndex
會立即返回該元素的索引。如果回調從不返回真值,或者數組的length
為0,則findIndex
返回-1。 與某些其他數組方法(如Array#some)不同,在稀疏數組中,即使對于數組中不存在的條目的索引也會調用回調函數。
回調函數調用時有三個參數:元素的值,元素的索引,以及被遍歷的數組。
如果一個 thisArg
參數被提供給 findIndex
, 它將會被當作this
使用在每次回調函數被調用的時候。如果沒有被提供,將會使用undefined
。
findIndex
不會修改所調用的數組。
在第一次調用callback
函數時會確定元素的索引范圍,因此在findIndex
方法開始執行之后添加到數組的新元素將不會被callback
函數訪問到。如果數組中一個尚未被callback
函數訪問到的元素的值被callback
函數所改變,那么當callback
函數訪問到它時,它的值是將是根據它在數組中的索引所訪問到的當前值。被刪除的元素仍然會被訪問到。
5.5 查找數組中首個質數元素的索引
// 以下示例查找數組中素數的元素的索引(如果不存在素數,則返回-1)。
function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) { //獲取平方根
if (element % start++ < 1) {
return false;
}
}
return element > 1;
}
console.log([4, 6, 8, 12].findIndex(isPrime)); // -1, not found
console.log([4, 6, 7, 12].findIndex(isPrime)); // 2
六.判斷方法:==至少有1個元素==通過了被提供的函數測試(some)
**some()**
方法測試數組中是不是至少有1個元素通過了被提供的函數測試。它返回的是一個Boolean類型的值。
注意:如果用一個空數組進行測試,在任何情況下它返回的都是
false
。
6.1語法
arr.some(callback(element[, index[, array]])[, thisArg])
6.2參數
-
callback
用來測試每個元素的函數,接受三個參數:
element
數組中正在處理的元素。index
可選數組中正在處理的元素的索引值。array
可選some()
被調用的數組。 -
thisArg
可選執行
callback
時使用的this
值。
6.3 返回值
數組中有至少一個元素通過回調函數的測試就會返回true
;所有元素都沒有通過回調函數的測試返回值才會為false。
6.4 描述
some()
為數組中的每一個元素執行一次 callback
函數,直到找到一個使得 callback 返回一個“真值”(即可轉換為布爾值 true 的值)。如果找到了這樣一個值,some()
將會立即返回 true
。否則,some()
返回 false
。callback
只會在那些”有值“的索引上被調用,不會在那些被刪除或從來未被賦值的索引上調用。
callback
被調用時傳入三個參數:元素的值,元素的索引,被遍歷的數組。
如果一個thisArg
參數提供給some(),它將被用作調用的 callback
的 this
值。否則, 它的 this
value將是 undefined
。this
的值最終通過callback來觀察,根據 the usual rules for determining the this
seen by a function的this判定規則來確定。
some()
被調用時不會改變數組。
some()
遍歷的元素的范圍在第一次調用 callback
. 前就已經確定了。在調用 some()
后被添加到數組中的值不會被 callback
訪問到。如果數組中存在且還未被訪問到的元素被 callback
改變了,則其傳遞給 callback
的值是 some()
訪問到它那一刻的值。已經被刪除的元素不會被訪問到。
6.5 案例
6.5.1 測試數組元素的值
下面的例子檢測在數組中是否有元素大于 10。
function isBiggerThan10(element, index, array) {
return element > 10;
}
[2, 5, 8, 1, 4].some(isBiggerThan10); // false
[12, 5, 8, 1, 4].some(isBiggerThan10); // true
6.5.2 使用箭頭函數測試數組元素的值
箭頭函數 可以通過更簡潔的語法實現相同的用例.
[2, 5, 8, 1, 4].some(x => x > 10); // false
[12, 5, 8, 1, 4].some(x => x > 10); // true
6.5.3 判斷數組元素中是否存在某個值
此例中為模仿 includes()
方法, 若元素在數組中存在, 則回調函數返回值為 true
:
var fruits = ['apple', 'banana', 'mango', 'guava'];
function checkAvailability(arr, val) {
return arr.some(function(arrVal) {
return val === arrVal;
});
}
checkAvailability(fruits, 'kela'); // false
checkAvailability(fruits, 'banana'); // true
6.5.4 使用箭頭函數判斷數組元素中是否存在某個值
var fruits = ['apple', 'banana', 'mango', 'guava'];
function checkAvailability(arr, val) {
return arr.some(arrVal => val === arrVal);
}
checkAvailability(fruits, 'kela'); // false
checkAvailability(fruits, 'banana'); // true
6.5.5 將任意值轉換為布爾類型
var TRUTHY_VALUES = [true, 'true', 1];
function getBoolean(value) {
'use strict';
if (typeof value === 'string') {
value = value.toLowerCase().trim();
}
return TRUTHY_VALUES.some(function(t) {
return t === value;
});
}
getBoolean(false); // false
getBoolean('false'); // false
getBoolean(1); // true
getBoolean('true'); // true
七.測試一個數組內的==所有元素==是否都能通過某個指定函數的測試(every)
**every()**
方法測試一個數組內的所有元素是否都能通過某個指定函數的測試。它返回一個布爾值。
注意:若收到一個空數組,此方法在一切情況下都會返回
true
。
7.1 語法
arr.every(callback(element[, index[, array]])[, thisArg])
7.2 參數
-
callback
用來測試每個元素的函數,它可以接收三個參數:
element
用于測試的當前值。index
可選用于測試的當前值的索引。array
可選調用every
的當前數組。 -
thisArg
執行
callback
時使用的this
值。
7.3 返回值
如果回調函數的每一次返回都為 truthy 值,返回 **true**
,否則返回 **false**
。
7.4 描述
every
方法為數組中的每個元素執行一次 callback
函數,直到它找到一個會使 callback
返回 falsy 的元素。如果發現了一個這樣的元素,every
方法將會立即返回 false
。否則,callback
為每一個元素返回 true
,every
就會返回 true
。callback
只會為那些已經被賦值的索引調用。不會為那些被刪除或從未被賦值的索引調用。
callback
在被調用時可傳入三個參數:元素值,元素的索引,原數組。
如果為 every
提供一個 thisArg
參數,則該參數為調用 callback
時的 this
值。如果省略該參數,則 callback
被調用時的 this
值,在非嚴格模式下為全局對象,在嚴格模式下傳入 undefined
。詳見 this
條目。
every
不會改變原數組。
every
遍歷的元素范圍在第一次調用 callback
之前就已確定了。在調用 every
之后添加到數組中的元素不會被 callback
訪問到。如果數組中存在的元素被更改,則他們傳入 callback
的值是 every
訪問到他們那一刻的值。那些被刪除的元素或從來未被賦值的元素將不會被訪問到。
every
和數學中的"所有"類似,當所有的元素都符合條件才會返回true
。正因如此,若傳入一個空數組,無論如何都會返回 true
。(這種情況屬于無條件正確:正因為一個空集合沒有元素,所以它其中的所有元素都符合給定的條件。)
7.5 案例
7.5.1檢測所有數組元素的大小
下例檢測數組中的所有元素是否都大于 10。
function isBigEnough(element, index, array) {
return element >= 10;
}
[12, 5, 8, 130, 44].every(isBigEnough); // false
[12, 54, 18, 130, 44].every(isBigEnough); // true
7.5.2 使用箭頭函數
箭頭函數為上面的檢測過程提供了更簡短的語法。
[12, 5, 8, 130, 44].every(x => x >= 10); // false
[12, 54, 18, 130, 44].every(x => x >= 10); // true
八.排序方法 sort
**sort()**
方法用原地算法對數組的元素進行排序,并返回數組。默認排序順序是在將元素轉換為字符串,然后比較它們的UTF-16代碼單元值序列時構建的
8.1 語法
arr.sort([compareFunction])
8.2 參數
-
compareFunction
可選用來指定按某種順序進行排列的函數。如果省略,元素按照轉換為的字符串的各個字符的Unicode位點進行排序。
firstEl
第一個用于比較的元素。secondEl
第二個用于比較的元素。
8.3 返回值
排序后的數組。請注意,數組已原地排序,并且不進行復制。
8.4 描述
如果沒有指明 compareFunction
,那么元素會按照轉換為的字符串的諸個字符的Unicode位點進行排序。例如 "Banana" 會被排列到 "cherry" 之前。當數字按由小到大排序時,9 出現在 80 之前,但因為(沒有指明 compareFunction
),比較的數字會先被轉換為字符串,所以在Unicode順序上 "80" 要比 "9" 要靠前。
如果指明了 compareFunction
,那么數組會按照調用該函數的返回值排序。即 a 和 b 是兩個將要被比較的元素:
如果
compareFunction(a, b)
小于 0 ,那么 a 會被排列到 b 之前;如果
compareFunction(a, b)
等于 0 , a 和 b 的相對位置不變。備注: ECMAScript 標準并不保證這一行為,而且也不是所有瀏覽器都會遵守(例如 Mozilla 在 2003 年之前的版本);如果
compareFunction(a, b)
大于 0 , b 會被排列到 a 之前。compareFunction(a, b)
必須總是對相同的輸入返回相同的比較結果,否則排序的結果將是不確定的。
所以,比較函數格式如下:
function compare(a, b) {
if (a < b ) { // 按某種排序標準進行比較, a 小于 b
return -1;
}
if (a > b ) {
return 1;
}
// a must be equal to b
return 0;
}
要比較數字而非字符串,比較函數可以簡單的以 a 減 b,如下的函數將會將數組升序排列
function compareNumbers(a, b) {
return a - b;
}
sort
方法可以使用 函數表達式 方便地書寫:
var numbers = [4, 2, 5, 1, 3];
numbers.sort(function(a, b) {
return a - b;
});
console.log(numbers);
也可以寫成:
var numbers = [4, 2, 5, 1, 3];
numbers.sort((a, b) => a - b);
console.log(numbers);
// [1, 2, 3, 4, 5]
對象可以按照某個屬性排序:
var items = [
{ name: 'Edward', value: 21 },
{ name: 'Sharpe', value: 37 },
{ name: 'And', value: 45 },
{ name: 'The', value: -12 },
{ name: 'Magnetic' },
{ name: 'Zeros', value: 37 }
];
// sort by value
items.sort(function (a, b) {
return (a.value - b.value)
});
// sort by name
items.sort(function(a, b) {
var nameA = a.name.toUpperCase(); // ignore upper and lowercase
var nameB = b.name.toUpperCase(); // ignore upper and lowercase
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
});
8.5 案例
8.5.1.字母排序
sort默認的排序方式為字母排序,根據二十六個字母依次排列,單詞之間比較,則先比較第一個字母,如果第一個字母相同則比較第二個字母,以此類推。
// 1.字母排序(sort默認排序)
var arr = ["za","zb","a","b","xc","xa"];
arr.sort();
console.log(arr);
// 運行結果:["a", "b", "xa", "xc", "za", "zb"]
8.5.2.sort數字排序
sort()中參數可以是方法函數,可以升序和降序輸出結果。
//2.sort數字排序
var array = [100,10,50,800,320,34,53];
array.sort(function(a,b){
//a-b升序,b-a降序
return b-a;
});
console.log(array);
//運行結果:[800, 320, 100, 53, 50, 34, 10]
注意:其中a,b都是表示這個數組里面的元素,如果是a-b則表示升序,如果是b-a則表示降序。
8.5.3.數組對象排序
最重要的還是這個對象屬性排序,當后臺給我們前端很多數據并且沒有排序時,我們一般都是要重新進行排序,而后臺給的數據往往是好幾層,不會像前面那種簡單的就一個數組,這個時候就要用sort中對象屬性排序了
// 3.對象屬性排序
var obj = [
{name:"lucy", num:400},
{name:"nancy", num:110},
{name:"maria", num:200}
];
obj.sort(compare("num"));
console.log(obj);
//數組對象屬性值排序
function compare(property){
return function(a,b){
//value1 - value2升序
//value2 - value1降序
var value1 = a[property];
var value2 = b[property];
return value1 - value2;//升序
}
}
運行結果:
[
{name:"nancy", num:110},
{name:"maria", num:200},
{name:"lucy", num:400}
]
注意:compare()中參數必須是這個對象的屬性名稱,而你要比較的這些對象里面,一定要有這個屬性名稱,否則會出錯。以上屬于個人總結,如果后期有什么補充會再次發布