difference
Returns the difference between two arrays.
Create a
Set
fromb
, then useArray.filter()
ona
to only keep values not contained inb
.
const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); }; // difference([1,2,3], [1,2,4]) -> [3] 複製程式碼
返回兩個陣列的不同。
建立一個b
陣列的集合,然後使用Array.filter()
對a
陣列進行過濾,過濾出不存在於陣列b
的元素。
➜ code cat difference.js
const difference = (a, b) => {
const s = new Set(b);
return a.filter(x => !s.has(x));
}
console.log(difference([1, 2, 3], [1, 2, 4]));
➜ code node difference.js
[ 3 ]
複製程式碼
關鍵點是主客體,這裡主體應該是第一個陣列,也就是a
,客體是陣列b
,返回的是不在主體a
裡的陣列元素。類似於集合的a - b
,不同點是a
、b
陣列都可以有重複的元素存在,而集合不允許重複元素存在。
這邏輯是很清晰的,先把b
陣列轉成集合存到s
中,然後去filter
陣列a
,只要把不存在於s
集合中的元素返回即可。記住filter
返回的是一個陣列。
differenceWith
Filters out all values from an array for which the comparator function does not return
true
.Use
Array.filter()
andArray.find()
to find the appropriate values.
const differenceWith = (arr, val, comp) => arr.filter(a => !val.find(b => comp(a, b))) // differenceWith([1, 1.2, 1.5, 3], [1.9, 3], (a,b) => Math.round(a) == Math.round(b)) -> [1, 1.2] 複製程式碼
從一個陣列中篩選出所有不滿足指定比較方法運算結果為true
的元素值的陣列。
使用Array.filter()
和Array.find()
來找出適當的值。
➜ code cat differenceWith.js
const differenceWith = (arr, val, comp) => arr.filter(a => !val.find(b => comp(a, b)));
console.log(differenceWith([1, 1.2, 1.5, 3], [1.9, 3], (a,b) => Math.round(a) == Math.round(b)));
➜ code node differenceWith.js
[ 1, 1.2 ]
複製程式碼
和difference
類似,主客體還是第一個陣列arr
。
我們可以先把意思進行拆分。
comp
執行結果為true
- 陣列
val.find()
去尋找comp(a, b)(a是arr元素,b是val元素)
執行結果為true
的值 arr
不要上面第2點中執行結果為true
的值
通俗點就是說去遍歷陣列arr
的所有元素,然後在陣列val
裡尋找comp
運算結果不為true的值。因為val.find()
方法如果找到就返回該值,否則返回undefined
,此時!val.find()
就是true
,arr.filter()
正是需要這樣運算結果的值。
distinctValuesOfArray
Returns all the distinct values of an array.
Use ES6
Set
and the...rest
operator to discard all duplicated values.const distinctValuesOfArray = arr => [...new Set(arr)]; // distinctValuesOfArray([1,2,2,3,4,4,5]) -> [1,2,3,4,5] 複製程式碼
返回陣列去重結果。
使用ES6
的集合Set
和ES6
的擴充套件運算子…
把重複的元素排除掉。
➜ code cat distinctValuesOfArray.js
const distinctValuesOfArray = arr => [...new Set(arr)];
console.log(distinctValuesOfArray([1, 2, 2, 3, 4, 4, 5]));
➜ code node distinctValuesOfArray.js
[ 1, 2, 3, 4, 5 ]
複製程式碼
實際上ES6
的集合Set
乾的事,沒啥可說。
dropElements
Removes elements in an array until the passed function returns
true
. Returns the remaining elements in the array.Loop through the array, using
Array.slice()
to drop the first element of the array until the returned value from the function istrue
. Returns the remaining elements.
const dropElements = (arr, func) => { while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1); return arr; }; // dropElements([1, 2, 3, 4], n => n >= 3) -> [3,4] 複製程式碼
剔除掉陣列元素直到指定方法運算結果第一次為true
為止。
迴圈一個陣列,使用Array.slice
每次去刪除該陣列的第一個元素直到指定方法運算結果為true
,返回的是剩餘元素組成的陣列。
➜ code cat dropElements.js
const dropElements = (arr, func) => {
while (arr.length > 0 && !func(arr[0])) arr = arr.slice(1);
return arr;
};
console.log(dropElements([1, 2, 3, 4], n => n >= 3));
➜ code node dropElements.js
[ 3, 4 ]
複製程式碼
這裡用while
進行迴圈,迴圈條件是陣列的長度大於0
並且陣列的第一個元素按照指定方法執行結果為false
,如果滿足條件,使用arr.slice(1)
將arr
第一個元素刪除掉。直到while
迴圈退出,返回此時的arr
。
這裡的邊界條件是陣列長度為0
,這時候就不進入while
迴圈,直接返回空陣列。
dropRight
Returns a new array with
n
elements removed from the right.Use
Array.slice()
to slice the remove the specified number of elements from the right.
const dropRight = (arr, n = 1) => arr.slice(0, -n); //dropRight([1,2,3]) -> [1,2] //dropRight([1,2,3], 2) -> [1] //dropRight([1,2,3], 42) -> [] 複製程式碼
返回陣列從右邊開始剔除掉n
個元素後的陣列。
使用Array.slice()
切掉從右邊開始計算的指定數目的元素。
➜ code cat dropRight.js
const dropRight = (arr, n = 1) => arr.slice(0, -n);
console.log(dropRight([1, 2, 3]));
console.log(dropRight([1, 2, 3], 2));
console.log(dropRight([1, 2, 3], 42));
➜ code node dropRight.js
[ 1, 2 ]
[ 1 ]
[]
複製程式碼
n
的預設值是1
,所以不傳第二個引數的時候會刪掉陣列的最後一個元素。
-n
不好理解嗎?變換一下就好了arr.slice(0, -n)
跟arr.slice(0, arr.length + (-n))
是一樣的。
slice(m, n)
對應就是[m, n),包含下界,不包含上屆。
everyNth
Returns every nth element in an array.
Use
Array.filter()
to create a new array that contains every nth element of a given array.const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1); // everyNth([1,2,3,4,5,6], 2) -> [ 2, 4, 6 ] 複製程式碼
返回一個新的陣列,陣列包含每nth
的元素,即nth
倍數的元素。
使用Array.filter()
建立一個包含nth
倍數元素的新陣列。
➜ code cat everyNth.js
const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1);
console.log(everyNth([1, 2, 3, 4, 5, 6], 2));
➜ code node everyNth.js
[ 2, 4, 6 ]
複製程式碼
判斷是否nth
倍數只需要知道該元素的索引加1
後能不能被nth
整除即可。
如果是我的話我會這麼寫(e, i) => (i + 1) % nth === 0
,可能這樣比較符合我的思維習慣。
filterNonUnique
Filters out the non-unique values in an array.
Use
Array.filter()
for an array containing only the unique values.const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); // filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5] 複製程式碼
過濾掉不唯一元素後返回的陣列。
使用Array.filter()
去篩選滿足陣列元素唯一性的元素。
➜ code cat filterNonUnique.js
const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i));
console.log(filterNonUnique([1, 2, 2, 3, 4, 4, 5]));
➜ code node filterNonUnique.js
[ 1, 3, 5 ]
複製程式碼
方法用得很巧,一個數如果出現在一個陣列超過一次,那麼該數在陣列中的左索引indexOf
(從左邊數第一次出現該數的索引)和右索引lastIndexOf
(從右邊數第一次出現該數的索引)一定不相等。
反過來說左索引等於右索引,該數在陣列中只出現一次,滿足唯一性。
這裡和distinctValuesOfArray
的區別是,distinctValuesOfArray
刪掉了重複的元素,只留一個;filterNonUnique
刪掉了所有重複元素,一個不留。
flatten
Flattens an array.
Use a new array and concatenate it with the spread input array causing a shallow denesting of any contained arrays.
const flatten = arr => [ ].concat( ...arr ); // flatten([1,[2],3,4]) -> [1,2,3,4] 複製程式碼
攤平一個陣列。
Array.concat()
、空陣列[]
和ES6
的擴充套件運算子…
來攤平一個陣列。這裡是淺度攤平,即只攤平一層。
➜ code cat flatten.js
const flatten = arr => [].concat(...arr);
console.log(flatten([1, [2], 3, 4]));
console.log(flatten([1, [[2], 5], 3, 4]));
➜ code node flatten.js
[ 1, 2, 3, 4 ]
[ 1, [ 2 ], 5, 3, 4 ]
複製程式碼
主要是用[]
和ES6
的擴充套件運算子…
對arr
運算結果concat
連線起來。
與deepFlatten
的區別就是flatten
只攤平一層,deepFlatten
深度攤平。
個人翻譯水平有限,歡迎大家在issues上批評指正。JavaScript30秒, 從入門到放棄之Array(二)