最近很火的github
上的庫30-seconds-of-code
,特別有意思,代碼也很優雅。javascript
Calculates the greatest common denominator (gcd) of an array of numbers.java
Use
Array.reduce()
and thegcd
formula (uses recursion) to calculate the greatest common denominator of an array of numbers.nodeconst arrayGcd = arr =>{ const gcd = (x, y) => !y ? x : gcd(y, x % y); return arr.reduce((a,b) => gcd(a,b)); } // arrayGcd([1,2,3,4,5]) -> 1 // arrayGcd([4,8,12]) -> 4 複製代碼
計算數組的最大公約數。python
使用Array.reduce()
和gcd
公式(使用遞歸)來計算一個數組的最大公約數。git
➜ code cat arrayGcd.js
const arrayGcd = arr => {
const gcd = (x, y) => !y ? x : gcd(y, x % y);
return arr.reduce((a, b) => gcd(a, b));
}
console.log(arrayGcd([1, 2, 3, 4, 5]));
console.log(arrayGcd([4, 8, 12]));
➜ code node arrayGcd.js
1
4
複製代碼
gcd
即歐幾里德算法,具體不表,自查。這裏用到了數組的reduce方法,至關簡潔,reduce不太瞭解的話,看下mdn就明白。es6
Calculates the lowest common multiple (lcm) of an array of numbers.github
Use
Array.reduce()
and thelcm
formula (uses recursion) to calculate the lowest common multiple of an array of numbers.算法const arrayLcm = arr =>{ const gcd = (x, y) => !y ? x : gcd(y, x % y); const lcm = (x, y) => (x*y)/gcd(x, y) return arr.reduce((a,b) => lcm(a,b)); } // arrayLcm([1,2,3,4,5]) -> 60 // arrayLcm([4,8,12]) -> 24 複製代碼
計算一個數組的最小公倍數。數組
使用Array.reduce()
和lcm
公式(使用遞歸)來計算一個數組的最大公約數。bash
➜ code cat arrayLcm.js
const arrayLcm = arr => {
const gcd = (x, y) => (!y ? x : gcd(y, x % y));
const lcm = (x, y) => x * y / gcd(x, y);
return arr.reduce((a, b) => lcm(a, b));
};
console.log(arrayLcm([1, 2, 3, 4, 5]));
console.log(arrayLcm([4, 8, 12]));
➜ code node arrayLcm.js
60
24
複製代碼
lcm
算法用到了前面的gcd
算法,關鍵點是兩個數的最大公約數和最小公倍數的乘積正好就是這兩個數的乘積。
Returns the maximum value in an array.
Use
Math.max()
combined with the spread operator (...
) to get the maximum value in the array.const arrayMax = arr => Math.max(...arr); // arrayMax([10, 1, 5]) -> 10 複製代碼
返回數組中最大的值。
使用Math.max()
和ES6
的擴展運算符…
返回數組中最大的值。
➜ code cat arrayMax.js
const arrayMax = arr => Math.max(...arr);
console.log(arrayMax([10, 1, 5]));
➜ code node arrayMax.js
10
複製代碼
實際上就是Math.max()
乾的事,沒啥可說的了。
Returns the minimum value in an array.
Use
Math.min()
combined with the spread operator (...
) to get the minimum value in the array.const arrayMin = arr => Math.min(...arr); // arrayMin([10, 1, 5]) -> 1 複製代碼
返回數組中最小的值。
使用Math.min()
和ES6
的擴展運算符…
返回數組中最小的值。
➜ code cat arrayMin.js
const arrayMin = arr => Math.min(...arr);
console.log(arrayMin([10, 1, 5]));
➜ code node arrayMin.js
1
複製代碼
實際上就是Math.min()
乾的事,沒啥可說的了。
Chunks an array into smaller arrays of a specified size.
Use
Array.from()
to create a new array, that fits the number of chunks that will be produced. UseArray.slice()
to map each element of the new array to a chunk the length ofsize
. If the original array can't be split evenly, the final chunk will contain the remaining elements.const chunk = (arr, size) => Array.from({length: Math.ceil(arr.length / size)}, (v, i) => arr.slice(i * size, i * size + size)); // chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],[5]] 複製代碼
按照給定的size
將一個數組切分紅含有size
個數的更小數組塊的數組。
使用Array.from()
生產新的符合定義的數組。使用Array.slice()
來截取指定size
個元素組成新的數組塊。若是原數組長度不能被size
整除,最後的剩餘的那些元素將歸屬於最後一個塊。
➜ code cat chunk.js
const chunk = (arr, size) =>
Array.from({ length: Math.ceil(arr.length / size) }, (v, i) =>
arr.slice(i * size, i * size + size)
);
console.log(chunk([1, 2, 3, 4, 5], 2));
➜ code node chunk.js
[ [ 1, 2 ], [ 3, 4 ], [ 5 ] ]
複製代碼
Array.from(arrayLike, mapFn, thisArg)
這個方法呢,第一個參數是一個類數組或者可迭代的對象,第二個參數是一個應用在每個數組元素上的方法,第三個參數就是改變this
的指向了。通俗說就是指定誰是你的爸爸。
這裏用了一個{ length: Math.ceil(arr.length / size) }
迭代對象,length
指定了迭代次數,它正好按照size
分塊後的數組長度正好就是原數組長度除以size
向上取整的值。向上取整就是爲了知足不能徹底整除的狀況。好比5個元素按照2個進行分塊,分了兩塊兩個元素的,剩最後一個元素成了獨立塊,總共3個元素。
(v, i)
,因爲迭代的時候數組在每個位置上都是以undefined
初始化的,因此v
一直都是undefined
。
arr.slice(i * size, i * size + size)
迭代過程當中每次截取size
個數的元素組成新數組。這裏的i
就是隨着迭代變化,好比length
是3,i
就是0,1,2。
這裏的迭代相似python
裏的range
。
➜ code python
Python 3.6.4 (default, Dec 23 2017, 10:37:40)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import math
>>> arr = [1,2,3,4,5]
>>> size = 2
>>> for i in range(math.ceil(len(arr) / size)):
... print('index: ', i)
...
index: 0
index: 1
index: 2
複製代碼
Removes falsey values from an array.
Use
Array.filter()
to filter out falsey values (false
,null
,0
,""
,undefined
, andNaN
).const compact = arr => arr.filter(Boolean); // compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ] 複製代碼
移除掉數組裏falsey
的元素。(這個falsey
不太好翻譯,我記得好像不是錯誤的,應該是該值布爾運算值爲false
的,我我的經常使用!!
進行運算)。
使用Array.filter()
把false
、null
、0
、""
、undefined
和NaN
這些falsey
過濾掉。
➜ code cat compact.js
const compact = arr => arr.filter(Boolean);
console.log(compact([0, 1, false, 2, "", 3, "a", "e" * 23, NaN, "s", 34]));
➜ code node compact.js
[ 1, 2, 3, 'a', 's', 34 ]
複製代碼
Array.prototype.filter()
乾的,沒啥好說。
Counts the occurrences of a value in an array.
Use
Array.reduce()
to increment a counter each time you encounter the specific value inside the array.const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); // countOccurrences([1,1,2,1,2,3], 1) -> 3 複製代碼
統計一個元素在一個數組中出現的次數。
使用Array.reduce()
在遍歷過程當中若是指定元素在數組中出現,則增長它的次數值,默認次數爲0。
➜ code cat countOccurrences.js
const countOccurrences = (arr, value) =>
arr.reduce((a, v) => (v === value ? a + 1 : a + 0), 0);
console.log(countOccurrences([1, 1, 2, 1, 2, 3], 1));
console.log(countOccurrences([1, 1, 2, 1, 2, 3], 5));
➜ code node countOccurrences.js
3
0
複製代碼
三元運算符(v === value ? a + 1 : a + 0)
遍歷過程當中判斷遍歷數組值v
是否嚴格等於指定值value
,是,次數a+1
;否,a+0
。
最後的一個逗號後面的0,是這個初始值,即a=0
,這個懂reduce
方法都知道,特別指出是,由於這個函數必定會有返回值,若是指定元素沒有在數組中出現一次,返回值是0
,因此必須得初始化爲0
。
Deep flattens an array.
Use recursion. Use
Array.concat()
with an empty array ([]
) and the spread operator (...
) to flatten an array. Recursively flatten each element that is an array.const deepFlatten = arr => [].concat(...arr.map(v => Array.isArray(v) ? deepFlatten(v) : v)); // deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5] 複製代碼
深度攤平一個數組。
使用遞歸方法。結合Array.concat()
、空數組[]
和ES6
的擴展運算符…
來攤平一個數組,若是攤平的元素仍是一個數組,就再遞歸運用該方法。
➜ code cat deepFlatten.js
const deepFlatten = arr =>
[].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)));
console.log(deepFlatten([1, [2], [[3], 4], 5]));
➜ code node deepFlatten.js
[ 1, 2, 3, 4, 5 ]
複製代碼
三元運算符(Array.isArray(v) ? deepFlatten(v) : v)
判斷v
是不是一個數組,是,返回遞歸運用deepFlatten(v)
後的值;否,直接返回v
。
[].concat(...arr.map(fn))
用空數組把map
運算產生的數組進行…
擴展運算值拼接成結果數組返回。
該方法是深度攤平方法,在不少時候還有特定的攤平一層的需求,underscore
就有。實現的方法就是再加一個標誌參數進行處理便可。具體不講了。
應該會寫一個系列,今天先寫到這,明天繼續。
我的翻譯水平有限,歡迎你們在issues上批評指正。JavaScript30秒, 從入門到放棄