Ramda:嵌套循环中的参数

Ramda: Parameters in nested loops

我正在尝试使用 Ramda 重写 Javascript 无代码点。据我所知:

R.reject((something: Something) =>
  R.any(
    R.allPass([R.eqProps('property1', something),
               R.propEq('property2', otherObject)]),
    list1),
  list2 ?? [])

我的下一步是摆脱 something 变量(在我处理其他变量之前)。我怎样才能做到这一点?

原代码如下:

list2?.filter((something: Something) =>
  list1.every(item =>
    (item.property1 !== something.property1) || (item.property2 !== otherObject))
  )
)

这是使您的内部 lambda 点自由的最大努力(在没有可运行代码的情况下)。

list2?.filter((something: Something) =>
  R.all(
    R.pipe(
      R.repeat(1),
      R.ap([prop('property1'), R.prop('property2')]),
      R.zipWith(R.flip(R.applyTo), R.map(R.equals, [something.property1, otherObject])),
      R.reduce(R.and, true),
      R.not
    ),
    list1
  )
)

我真的不想费心去尝试让外层的 lambda 点无意义(我只是觉得它不会可读)

这是一个转换:

const otherObject = 42
const list1 = [{property1: 12, property2: 40}, {property1: 13, property2: 41}, {property1: 14, property2: 42}, {property1: 15, property2: 40}, {property1: 12, property2: 41}, {property1: 13, property2: 42}, {property1: 14, property2: 40}, {property1: 15, property2: 41}, {property1: 12, property2: 42}, {property1: 13, property2: 40}, {property1: 14, property2: 41}, {property1: 15, property2: 42}]
const list2 = [{property1: 10, foo: 'a'}, {property1: 11, foo: 'b'}, {property1: 12, foo: 'c'}, {property1: 13, foo: 'd'}, {property1: 14, foo: 'e'}, {property1: 15, foo: 'f'}, {property1: 16, foo: 'g'}]

const foo = list2 =>
  list2 .filter (
    (something) => list1 .every (
      item => (item.property1 !== something.property1) || (item.property2 !== otherObject)
    )
  )

const bar = filter (pipe (
  complement (eqProps ('property1')),
  either (complement (propEq ('property2', otherObject))),
  all (__, list1)
)) 

console .log ('vanilla:', foo (list2))
console .log ('ramda:',   bar (list2))
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js"></script>
<script> const {filter, pipe, complement, eqProps, either, propEq, all, __} = R</script>

正如评论中所讨论的,这远非毫无意义。当您尝试捕获 list1otherObject 自由变量时,它可能会变得更丑陋。

关于为什么您想将其转换为 Ramda,这是一个很好的问题。我是 Ramda 的创始人之一,也是 Ramda 的忠实粉丝,但它意味着在有帮助时可以使用,而不是一个目标。


到达那里对我来说不是一个干净的过程。我以一种迂回的方式来解决这个问题。如果你对血淋淋的细节感兴趣,你可以在这里看到我的许多步骤:

const otherObject = 42
const list1 = [{property1: 12, property2: 40}, {property1: 13, property2: 41}, {property1: 14, property2: 42}, {property1: 15, property2: 40}, {property1: 12, property2: 41}, {property1: 13, property2: 42}, {property1: 14, property2: 40}, {property1: 15, property2: 41}, {property1: 12, property2: 42}, {property1: 13, property2: 40}, {property1: 14, property2: 41}, {property1: 15, property2: 42}]
const list2 = [{property1: 10, foo: 'a'}, {property1: 11, foo: 'b'}, {property1: 12, foo: 'c'}, {property1: 13, foo: 'd'}, {property1: 14, foo: 'e'}, {property1: 15, foo: 'f'}, {property1: 16, foo: 'g'}]


console .log (
  list2 .filter (
    (something) => list1 .every (
      item => (item.property1 !== something.property1) || (item.property2 !== otherObject)
    )
  )
)


console .log (
  list2 .filter (
    (something) => list1 .every (
      anyPass ([
        complement (eqProps ('property1', something)),  
        complement (propEq ('property2', otherObject))
      ])
    )
  )
)

console .log (
  list2 .filter (
    (something) => 
      pipe (
        complement (eqProps ('property1')),
        of,
        concat ([complement (propEq ('property2', otherObject))]),
        anyPass,
        flip (all) (list1)
      ) (something)
  )
)


console .log (
  filter (
    (something) => 
      pipe (
        complement (eqProps ('property1')),
        of,
        concat ([complement (propEq ('property2', otherObject))]),
        anyPass,
        flip (all) (list1)
      ) (something),
    list2
  )
)

console .log (
  filter (pipe (
    complement (eqProps ('property1')),
    of,
    concat ([complement (propEq ('property2', otherObject))]),
    anyPass,
    flip (all) (list1)
  ), list2)
)

console .log (
  filter (pipe (
    complement (eqProps ('property1')),
    flip (append) ([complement (propEq ('property2', otherObject))]),
    anyPass,
    flip (all) (list1)
  )) (list2)
)

console .log ( 
  filter (pipe (
    complement (eqProps ('property1')),
    flip (append) ([complement (propEq ('property2', otherObject))]),
    anyPass,
    flip (all) (list1)
  )) (list2)
)

console .log (
  filter (pipe (
    complement (eqProps ('property1')),
    either (complement (propEq ('property2', otherObject))),
    all (__, list1)
  )) (list2) 
)

通过记录每一步的结果,我可以确保我没有在过程中破坏任何东西。 运行这个在the REPL,我可以实时看到。

但是您可以看到,这是一个迂回的过程让我得到了那个答案。 allPass 是一个错误的转弯,而 either 会更干净。最后我们得到了一些相当合理的东西,对自由变量取模。但过程并不顺利。