2015-12-31 7 views
2

В частности, у меня есть список объектов ImmutableJS, и я хочу условно обновлять записи до того же значения (которое может включать в себя только обновление всех их). Вариант использования показывает мин в тральщине, когда кто-то теряет игру. это достигается путем установки isVisible плитки истинно, если isMine также верно (или просто сделать каждую плитку видимым, независимо от isMine)Обновление нескольких записей в списке ImmutableJS

поэтому мой 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 истину) и показывает все плитки, которые являются минами (устанавливает isRevealed в true для каждой плитки с isMine равным true), но я могу сказать, просто глядя на нее, что она неэффективна и беспорядочна. Есть ли встроенный способ выполнить то, что я здесь делаю?

+0

В этом нет ничего ужасного, но если вы ужасно обеспокоены этим, просто используйте .withMutations, прежде чем отображать список. Но действительно, для нескольких сотен объектов в коде, не относящемся к производительности, кажется, не стоит слишком много думать. – pvg

ответ

0

С моей точки зрения, код довольно хорошо :) Есть, однако несколько трюков, которые могут сделать его лучше:

использования нескольких 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))) 
0

Вот функциональный подход программирования с использованием 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)) 
Смежные вопросы