Javascript 更新ImmutableJS列表中的多个条目

Javascript 更新ImmutableJS列表中的多个条目,javascript,list,dictionary,immutable.js,Javascript,List,Dictionary,Immutable.js,具体地说,我有一个ImmutableJS映射列表,我希望有条件地将记录更新为相同的值(这可能包括只更新所有记录)。当有人输掉游戏时,用例是在扫雷舰上显示地雷。这是通过将isVisible磁贴设置为true来实现的,如果isMine也为true(或者,不管isMine,只需使每个磁贴可见) 所以我的JS模式是这样的(其中数组是列表,对象是映射): 所以我想做的是,从game开始,对于isMine为真的每个磁贴,将isrevaled设置为真 这就是我想出来的,但它看起来太可怕了,我不得不希望有另一种

具体地说,我有一个ImmutableJS映射列表,我希望有条件地将记录更新为相同的值(这可能包括只更新所有记录)。当有人输掉游戏时,用例是在扫雷舰上显示地雷。这是通过将
isVisible
磁贴设置为true来实现的,如果
isMine
也为true(或者,不管
isMine
,只需使每个磁贴可见)

所以我的JS模式是这样的(其中数组是列表,对象是映射):

所以我想做的是,从
game
开始,对于
isMine
为真的每个磁贴,将
isrevaled
设置为真

这就是我想出来的,但它看起来太可怕了,我不得不希望有另一种方法

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),并显示了所有属于地雷的磁贴(将
isMine
等于true的每个磁贴的
isRevealed
设置为true),但我可以看出,只要看看它,它既低效又混乱。是否有一种内置的方法来完成我在这里所做的工作?

从我的角度来看,代码非常好:)但是有一些技巧可以让它变得更好:

在同一张
地图上使用多个
集合
,可以用一个
合并
代替:

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

这里有一个函数式编程方法,使用。这种方法的好处是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))

它似乎没有什么可怕的问题,但如果你非常担心它,在映射列表之前,只需使用.with突变。但实际上,对于非性能关键代码中的几百个对象来说,似乎不值得仔细考虑。
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))