1

我写了一个提取对象键的代码片段source(应该是未知的,所以我添加了一个不存在的键baz来提取。我提取的数组中的每个元素 - 我想添加它所在的键提取然后展平结果以获得单个数组。

我在编写代码时遇到了两个主要问题:

  1. 尝试使用S.insert时,它总是返回错误,因为对象值(数字{r:**<<number>>**})与我尝试添加到键的字符串类型不同Section{'Section': **'foo'**}例如)。我最终只是为了传达我的意图而改变了对象。
  2. 我没有设法编写一个适当的映射函数来抽象Maybe并让我访问里面的变量。所以我不得不使用S.maybeToNullable然后将值重新包装到Maybe.
  3. 有没有更好的方法来表达下面写的任何逻辑sanctuary

代码片段:

const S = require('sanctuary');
const source = {
  foo: [{ r: 1 }, { r: 2 }, { r: 3 }],
  bar: [{ r: 4 }, { r: 5 }, { r: 6 }],
}

const result =
  S.pipe([
    S.map(
      prop => {
        const nullable = S.maybeToNullable(S.value(prop)(source))
        return nullable ? S.Just(nullable.map(val => {val['Section'] = prop; return val})) : S.Nothing
      }
    ),
    S.justs,
    S.reduce(xs => x => [...xs, ...x])([])
  ])(['foo', 'bar', 'baz'])
4

1 回答 1

0

这是我的解决方案:

const S = require ('sanctuary');

//    source :: StrMap (Array { r :: Integer })
const source = {
  foo: [{r: 1}, {r: 2}, {r: 3}],
  bar: [{r: 4}, {r: 5}, {r: 6}],
  quux: [{r: 7}, {r: 8}],
};

//    result :: Array { r :: Integer, Section :: String }
const result =
S.filter (S.compose (S.flip (S.elem) (['foo', 'bar', 'baz']))
                    (S.prop ('Section')))
         (S.chain (S.pair (s => S.map (S.unchecked.insert ('Section') (s))))
                  (S.pairs (source)));

有几点需要注意:

  • S.pipe在这种情况下,我觉得不自然,因为有两个输入(source['foo', 'bar', 'baz'])。使用S.pipe将需要在管道中对这些输入之一进行硬编码。

  • S.insert不能用于更新记录,但S.unchecked.insert可用于此目的。当类型检查器认为我知道是正确的表达式不正确时,我很高兴能够抑制类型检查。

  • 从您的问题中我不清楚输出顺序是否重要。您的解决方案尊重部分名称数组的顺序;我的没有。让我知道输出顺序是否重要。

于 2019-11-15T11:08:17.630 回答