具体来说,我有一个ImmutableJS地图列表,我想有条件地将记录更新为相同的值(可能只包括更新所有记录)。当有人失去游戏时,用例就是在扫雷中揭示地雷。这是通过将isVisible
图块设置为true来实现的,如果isMine
也为真(或者只是让每个图块都可见,而不管isMine
)
所以我的JS模式是这样的(其中数组是列表,对象是地图):
game = {
isGameOver: false,
tiles: [
{
isMine: boolean,
isRevealed: boolean
},
...
]
}
所以我尝试做的是,从game
开始,为isRevealed
为真的每个图块设置isMine
为真。
这就是我想出来的,但它看起来非常糟糕我希望有另一种方式
function revealAll(game){
let revealedTiles;
revealedTiles = game.get('tiles').map(tile => {
if (tile.get('isMine')) {
tile = tile.set('isRevealed', true);
}
return tile;
});
return game.set('isGameOver', true).set('tiles', revealedTiles);
}
这成功结束了游戏(将isGameOver
设置为true)并显示所有作为地雷的图块(对于isRevealed
等于true的每个图块,将isMine
设置为true),但是我只能看着它既低效又凌乱。是否有内置的方法来完成我在这里做的事情?
答案 0 :(得分:1)
从我的角度来看,代码非常好:)但是有一些技巧可以让它变得更好:
在同一个set
上使用多个Map
可以替换为一个merge
:
return game.merge({
'isGameOver': true,
'tiles': revealedTiles
});
此外,更新单个磁贴可以更好地完成:
revealedTiles = game.get('tiles').map(
tile => tile.update('isRevealed', (v) => tile.get('isMine') || v))
所以你最终得到:
function revealAll(game){
let revealedTiles
revealedTiles = game.get('tiles').map(
tile => tile.update('isRevealed', (v) => tile.get('isMine') || v))
return game.merge({
'isGameOver': true,
'tiles': revealedTiles
});
}
或者,你可以这样做:
const revealAll = (game) =>
game
.set('isGameOver', true)
.update('tiles', (tiles) => tiles.map(
tile => tile.update('isRevealed', (v) => tile.get('isMine') || v)))
答案 1 :(得分:0)
这是使用mudash的函数式编程方法。这种方法的好处是mudash将处理ImmutableJS数据类型以及标准JS(或两者的混合)。因此,无论格式如何,都可以使用您的功能。
import _ from 'mudash'
import fp from 'mudash/fp'
const revealAll = _.compose(
fp.set('isGameOver', true),
fp.update('tiles', fp.map((tile) =>
_.update(tile, 'isRevealed', (isRevealed) => _.get(tile, 'isMine') || isRevealed)))
)
const gameMutable = {
isGameOver: false,
tiles: [
{
isMine: false,
isRevealed: false
},
{
isMine: true,
isRevealed: false
},
{
isMine: false,
isRevealed: true
},
{
isMine: true,
isRevealed: true
}
]
}
const gameImmutable = _.immutable(gameMutable)
console.log(revealAll(gameMutable))
console.log(revealAll(gameImmutable))