如何映射一对多?
How to map one to many?
简单的问题是我有数组 ['a', 'b', 3, 'c']
并且我想用 null, null, null
改变 3
像这样 ['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(如果可能的话使用无点样式)?
您可以使用 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>
简单的问题是我有数组 ['a', 'b', 3, 'c']
并且我想用 null, null, null
改变 3
像这样 ['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(如果可能的话使用无点样式)?
您可以使用 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>