0

如何使用 ramdasequence遍历字典?

给定以下字典

cars = {color: ['yellow', 'red'], year: [2017], model: ['coup', 'sedan']}

我想产生遍历的结果

all_cars = [
    {color: 'yellow', year: 2017, model: 'coup'},
    {color: 'yellow', year: 2017, model: 'sedan'},
    {color: 'red', year: 2017, model: 'coup'},
    {color: 'red', year: 2017, model: 'sedan'}
]

R.sequence在空列表的列表中使用结果

R.sequence(R.of, cars)
[[]]

如果我遍历列表而不是字典,它会产生正确的笛卡尔积,但结果(当然)是列表而不是字典。

R.sequence(R.of, [['yellow', 'red'], [2017], ['coup', 'sedan']])
[["yellow", 2017, "coup"], ["yellow", 2017, "sedan"], ["red", 2017, "coup"], ["red", 2017, "sedan"]]
4

1 回答 1

1

我可以想到两种方法来做到这一点,一种涉及sequence,另一种不涉及。

这个使用你sequence(of)上面的电话:

const convert = lift(map)(
  compose(zipObj, keys), 
  compose(sequence(of), values)
)

const all_cars = convert(cars);

另一个是通过我常用的技术构建的,即通​​过一次又一次的转换不断改变输出,直到我得到我想要的:

const combine = pipe(
  toPairs,
  map(apply(useWith(map, [objOf, identity]))),
  reduce(xprod, [[]]),
  map(flatten),
  map(mergeAll)
)

const all_cars = combine(cars)

通过在多个列表中引入交叉积,这可能会更清楚一点:

const xproduct = reduce(pipe(xprod, map(unnest)), [[]])

const combine = pipe(
  toPairs,
  map(apply(useWith(map, [objOf, identity]))),
  xproduct,
  map(mergeAll)
)

第二个版本是我第一次尝试这个问题时想出的。然后,当我查看您尝试过的内容时,我得到了第一个版本。第一个版本对我来说看起来更干净,尽管第二个版本中的大多数单独步骤都是微不足道的。但由于其中有一个重要的步骤,所以第一个似乎是总体赢家。

您可以在 Ramda REPL 上看到第一个第二个。

于 2017-11-14T19:52:14.770 回答