有意思
最近很火的github
上的庫30-seconds-of-code
,特別有意思,程式碼也很優雅。
- 能學es6
- 自己翻譯,能學英語
- 程式碼很美,很優雅,美即正義
- 函式式表達,享受
arrayGcd
Calculates the greatest common denominator (gcd) of an array of numbers.
Use
Array.reduce()
and thegcd
formula (uses recursion) to calculate the greatest common denominator of an array of numbers.
const 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 複製程式碼
計算陣列的最大公約數。
使用Array.reduce()
和gcd
公式(使用遞迴)來計算一個陣列的最大公約數。
➜ 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就明白。
arrayLcm
Calculates the lowest common multiple (lcm) of an array of numbers.
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
公式(使用遞迴)來計算一個陣列的最大公約數。
➜ 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
演算法,關鍵點是兩個數的最大公約數和最小公倍數的乘積正好就是這兩個數的乘積。
arrayMax
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()
乾的事,沒啥可說的了。
arrayMin
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()
乾的事,沒啥可說的了。
chunk
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
複製程式碼
compact
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()
乾的,沒啥好說。
countOccurrences
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
。
deepFlatten
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秒, 從入門到放棄