更新ImmutableJS列表中的多个条目

时间:2015-12-31 22:07:50

标签: javascript list dictionary immutable.js

具体来说,我有一个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),但是我只能看着它既低效又凌乱。是否有内置的方法来完成我在这里做的事情?

2 个答案:

答案 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))