JavaScript30秒, 從入門到放棄之Array(二)

difference

Returns the difference between two arrays.javascript

Create a Set from b, then use Array.filter() on a to only keep values not contained in b.java

const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); };
// difference([1,2,3], [1,2,4]) -> [3]

返回兩個數組的不一樣。node

建立一個b數組的集合,而後使用Array.filter()a數組進行過濾,過濾出不存在於數組b的元素。git

➜  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,不一樣點是ab數組均可以有重複的元素存在,而集合不容許重複元素存在。github

這邏輯是很清晰的,先把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() and Array.find() to find the appropriate values.app

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的元素值的數組。oop

使用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

咱們能夠先把意思進行拆分。

  1. comp運行結果爲true
  2. 數組val.find()去尋找comp(a, b)(a是arr元素,b是val元素)運行結果爲true的值
  3. arr不要上面第2點中運行結果爲true的值

通俗點就是說去遍歷數組arr的全部元素,而後在數組val裏尋找comp運算結果不爲true的值。由於val.find()方法若是找到就返回該值,不然返回undefined,此時!val.find()就是truearr.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的集合SetES6的擴展運算符把重複的元素排除掉。

➜  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 is true. 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(二)
微信公衆號:JavaScript30秒, 從入門到放棄之Array(二)

相關文章
相關標籤/搜索