點燈坊

學而時習之,不亦悅乎

如何將 Array 中的字串轉成一層 Array ?

Sam Xiao's Avatar 2019-08-07

chain() 在實務上其實常常用到,只在於你有沒有發現而已,map(split()) 典型會產生兩層 Array,此時可使用 chain() 加以重構。

Version

macOS Mojave 10.14.5
VS Code 1.35.0
Quokka 1.0.224
ECMAScript 2019
Ramda 0.26.1

Functional

import { pipe, flatten, map, split } from 'ramda';

let data = [
  'FP in JavaScript, Rx in Action, Speaking JavaScript'
];

let usrFn = pipe(
  map(split(',')), 
  flatten
);

usrFn(data); // ?

FP in JavaScript, Rx in Action, Speaking JavaScript 為 string,若要變成 array,勢必要使用 split(','),但 split() 結果為 array,再使用 map() 會變成兩層 array,因此最後要使用 flatten() 將兩層 array 攤平。

split000

chain()

import { chain, split } from 'ramda'

let data = [
  'FP in JavaScript, Rx in Action, Speaking JavaScript'
];

let usrFn = chain(split(','));

usrFn(data); // ?

pipe(map, flatten) 相當於 chain(),可利用 FP 的 associative laws 使用 chain() 加以化簡。

chain()
(a → b) → [a] → [b]
相當於 flatten()map() 組合

(a -> b):相當於 map function

[a]:data 為 array

[b]:回傳攤平後的 array

split001

Conclusion

  • 當結果為一層 array,但過程中卻出現兩層 array,最後必須靠 flatten() 攤平時,常常就是可用 chain() 的時機
  • 若一開始沒看出 chain() 也沒關係,先使用 map() 實作,當最後看到 pipe(map, flatten) 時,再用 chain() 重構

Reference

Ran Bar-Zip, Using flatMap in ES2019
Ramda, chain()
Ramda, flatten()
Ramda, map()
Ramda, split()
Ramda, pipe()