内容简介:當 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》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。