Как сопоставить один ко многим? - PullRequest
0 голосов
/ 13 марта 2020

Упрощенный вопрос: у меня есть массив ['a', 'b', 3, 'c'], и я хочу изменить 3 на null, null, null, как это ['a', 'b', null, null, null, 'c'] как мне это сделать с Рамдой?

это мой полный код

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 ноль , как это ...

[
  { 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' },
  ...
]

Итак, я написал код, который мне нужен без Рамды, вот так ...

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
}

Но я понятия не имею, как это сделать с Рамдой (если возможно, со стилем без точек) )

1 Ответ

3 голосов
/ 13 марта 2020

Вы можете использовать R.chain для итерации элементов массива и выравнивания результатов. Если элемент является числом, используйте повтор для создания массива 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>
...