【问题标题】:How to map one to many?如何映射一对多?
【发布时间】:2020-06-25 14:51:43
【问题描述】:

简单的问题是我有数组 ['a', 'b', 3, 'c'] 并且我想将 3 更改为 null, null, null 像这样 ['a', 'b', null, null, null, 'c'] 我如何使用 Ramda 来做到这一点?

这是我的完整代码

const R = require('ramda')

const getBoardStateFromBoardString = R.pipe(
    R.split(''),
    R.map(
        R.cond([
            [
                R.test(/[bfmterk]/),
                R.assoc('piece', R.__, { color: 'b' })
            ],
            [
                R.test(/[BFMTERK]/),
                R.assoc('piece', R.__, { color: 'w' })
            ],
            [
                R.test(/\d/),
                R.pipe(
                    R.assoc('padding', R.__, {}),
                    R.evolve({ padding: parseInt })
                )
            ],
            [
                R.equals('/'),
                R.always({ padding: 8 })
            ]
        ])
    ),
)

console.log(getBoardStateFromBoardString('rmtektmr/8/bbbbbbbb/8/8/BBBBBBBB/8/RMTKETMR'))

结果

[
  { color: 'b', piece: 'r' },
  { color: 'b', piece: 'm' },
  { color: 'b', piece: 't' },
  { color: 'b', piece: 'e' },
  { color: 'b', piece: 'k' },
  { color: 'b', piece: 't' },
  { color: 'b', piece: 'm' },
  { color: 'b', piece: 'r' },
  { padding: 8 },
  { padding: 8 },
  { padding: 8 },
  { color: 'b', piece: 'b' },
  ...
]

我想要的是像这样将单个 { padding: 8 } 映射到 8 null ...

[
  { color: 'b', piece: 'r' },
  { color: 'b', piece: 'm' },
  { color: 'b', piece: 't' },
  { color: 'b', piece: 'e' },
  { color: 'b', piece: 'k' },
  { color: 'b', piece: 't' },
  { color: 'b', piece: 'm' },
  { color: 'b', piece: 'r' },

  null,
  null,
  null,
  null,
  null,
  null,
  null,
  null,

  null,
  null,
  null,
  null,
  null,
  null,
  null,
  null,

  null,
  null,
  null,
  null,
  null,
  null,
  null,
  null,

  { color: 'b', piece: 'b' },
  ...
]

所以我写了我想要的没有 Ramda 的代码...

function getBoardStateFromBoardString(boardString) {
    const boardState = Array(128)
    let i = 0
    for (const symbol of boardString) {
        if (/[bfmterk]/.test(symbol)) {
            boardState[i] = {
                piece: symbol,
                color: 'b'
            }
            i++
        } else if (/[BFMTERK]/.test(symbol)) {
            boardState[i] = {
                piece: symbol,
                color: 'w'
            }
            i++
        } else if (/\d/.test(symbol)) {
            i += parseInt(symbol, 10)
        } else if (symbol === '/') {
            i += 8
        }
    }

    return boardState
}

但我不知道如何处理 Ramda(如果可能的话,使用无点样式)?

【问题讨论】:

    标签: javascript functional-programming ramda.js


    【解决方案1】:

    您可以使用 R.chain 来迭代数组项,并将结果展平。如果项目是数字,请使用 repeat 创建一个包含 null 值的数组。

    const { chain, when, is, repeat } = R
    
    const fn = chain(when(is(Number), repeat(null)))
    
    const arr = ['a', 'b', 3, 'c']
    
    const result = fn(arr)
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>

    在您的情况下,您可以将 R.cond 与 R.chain 一起使用,并将填充对象的创建替换为重复的 null

    const { pipe, split, chain, cond, test, applySpec, identity, always, equals, repeat } = R
    
    const getBoardStateFromBoardString = pipe(
      split(''),
      chain(
        cond([
          [
              test(/[bfmterk]/),
              applySpec({
                piece: identity,
                color: always('b')
              })
          ],
          [
              test(/[BFMTERK]/),
              applySpec({
                piece: identity,
                color: always('w')
              })
          ],
          [
              test(/\d/),
              repeat(null)
          ],
          [
              equals('/'),
              always(repeat(null, 8))
          ]
        ])
      ),
      
    )
    
    const result = getBoardStateFromBoardString('rmtektmr/8/bbbbbbbb/8/8/BBBBBBBB/8/RMTKETMR')
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>

    【讨论】:

    • 哇,它就像一个魅力。我坚持这个问题几个小时。我用完了在谷歌上搜索的关键字。许多网站上的教程都没有提到 R.chain。而且我不知道如何漂亮地创建新对象,所以你用 R.applySpec 救了我的命。谢谢!
    • 不客气 :) 您通常会将 R.chain 的这个用例视为平面图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-25
    • 1970-01-01
    • 2020-04-07
    • 1970-01-01
    相关资源
    最近更新 更多