内容简介:當 Data 為兩個 Array,而結果希望為單一 Array 或單一 Object,我們會使用VS Code 1.33.1Quokka 1.0.209
當 Data 為兩個 Array,而結果希望為單一 Array 或單一 Object,我們會使用 zip
系列的 zip()
、 zipObj()
與 zipWith()
, zip
也是 FP 很具代表性的 Higher Order Function。
Version
VS Code 1.33.1
Quokka 1.0.209
Ramda 0.26.1
Imperative
let girls = [ { name: 'Mary' }, { name: 'Jessie' } ]; let boys = [ { name: 'John', car: 'BMW' }, { name: 'Tomy', car: 'TOYOTA' }, { name: 'Paul', car: 'Benz' } ]; let zip = (arr1, arr2) => { let result = []; let len = Math.min(arr1.length, arr2.length); for (let idx = 0; idx < len; idx++) { result[idx] = [arr1[idx], arr2[idx]]; } return result; }; console.dir(zip(girls, boys));
有 girls
與 boys
兩 array 加以合併配對成新 array,其新 length 由較小 array 決定,新 array 同時包含兩個 array 的 element。
若使用 imperative 方式實現,先由 Math.min()
決定 length,會使用 for loop
一一合併配對成新 array 而成為 nested array。
Functional
import { map, addIndex, min, max } from 'ramda'; let girls = [ { name: 'Mary' }, { name: 'Jessie' } ]; let boys = [ { name: 'John', car: 'BMW' }, { name: 'Tomy', car: 'TOYOTA' }, { name: 'Paul', car: 'Benz' } ]; let mapIndex = addIndex(map); let zip = (arr1, arr2) => { let minArr = min(arr1, arr2); let maxArr = max(arr1, arr2); return mapIndex((x, i) => [x, maxArr[i]], minArr); }; console.dir(zip(girls, boys));
由於新 array 的 length 不變,因此也可以使用 map()
處理,不過有幾點必須解決:
- 由於新 array 的 length 會由較小的 array 決定,因此
map()
的 callback 必須包含 index 參數,此時必須使用addIndex(map)
產生新的mapIndex()
- 再套用
mapIndex()
前,須由min()
與max()
決定哪一個 array 比較大,將較小的 array 以 data 傳進mapIndex()
zip()
import { zip } from 'ramda'; const girls = [ { name: 'Mary' }, { name: 'Jessie' } ]; const boys = [ { name: 'John', car: 'BMW' }, { name: 'Tomy', car: 'TOYOTA' }, { name: 'Paul', car: 'Benz' } ]; console.dir(zip(girls, boys));
Ramda 已經提供了 zip()
,可將兩個 array 合併配對在一起。
zip()
[a] -> [b] -> [[a], [b]]
將兩個 array 合併配對成單一 array,配對在一起的 element 會在同一個 array
[a]
:普通 array
[b]
:普通 array
[[a], [b]]
:合併配對過的 array
zipWith()
import { zipWith } from 'ramda'; const girls = [ { name: 'Mary' }, { name: 'Jessie' } ]; const boys = [ { name: 'John', car: 'BMW' }, { name: 'Tomy', car: 'TOYOTA' }, { name: 'Paul', car: 'Benz' } ]; console.dir(zipWith((x, y) => [x, y], girls, boys));
zip()
使適合預設的配對行為,若要自行以 callback 描述配對方式,可以使用 zipWith()
。
zipWith()
((a, b) → c) → [a] → [b] → [c]
自行提供 callback 的 zip()
((a, b) → c)
:callback 描述配對方式
[a]
:普通 array
[b]
:普通 array
[c]
:合併配對過的 array
zip()
相當於 zipWith((x, y) => [x, y])()
。
import { zipWith } from 'ramda'; let girls = [ { name: 'Mary' }, { name: 'Jessie' } ]; let boys = [ { name: 'John', car: 'BMW' }, { name: 'Tomy', car: 'TOYOTA' }, { name: 'Paul', car: 'Benz' } ]; console.dir(zipWith((x, y) => `${x.name}: ${y.car}`, girls, boys));
若配對後我們不希望是 nested array,而是一層 array 內以 string 描述,這種需求 zip()
就做不到,必須使用 zipWith()
。
zipObj()
import { zip, fromPairs, pipe } from 'ramda'; let girls = ['Mary', 'Jessie']; let cars = ['BMW', 'TOYOTA', 'Benz']; let zipObj = pipe( zip, fromPairs ); console.dir(zipObj(girls, cars));
若兩個 array,各自提供 object property 的 key 與 value,最後合併配對成單一 object。
我們可以將 zip()
與 fromPairs()
加以組合成 zipObj()
。
import { zipObj } from 'ramda'; let girls = ['Mary', 'Jessie']; let boys = ['BMW', 'TOYOTA', 'Benz']; console.dir(zipObj(girls, boys));
Ramda 已經提供 zipObj()
,可直接使用。
zipObj()
[String] → [*] → {String: *}
將兩個 array 配對合併成單一 object
[String]
:提供 key 的 array
[*]
:提供 value 的 array
{String: *}
:配對合併成單一 object
Conclusion
zip zip() zipWith() zipObj()
Reference
以上所述就是小编给大家介绍的《Ramda 之 Zip》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Sprint
Jake Knapp、John Zeratsky、Braden Kowitz / Simon & Schuster / 2016-3-8 / GBP 14.60
媒体推荐 “Every business leader I know worries about the same thing: Are we moving fast enough? The genius of Jake Knapp’s Sprint is its step-by-step breakdown of what it takes to solve big problems an......一起来看看 《Sprint》 这本书的介绍吧!