2015-12-31 32 views
2

特別是,我有一個ImmutableJS地圖列表,並且我想有條件地將記錄更新爲相同的值(可能只包括更新所有這些值)。該用例揭示了掃雷中的地雷,當某人失去遊戲時。這是由isVisible瓷磚設置爲true完成的,如果isMine也是如此(或者只是讓每瓦可見,無論isMine更新ImmutableJS列表中的多個條目

所以我的JS架構是這樣的(其中數組列表和對象是地圖):

game = { 
    isGameOver: false, 
    tiles: [ 
    { 
     isMine: boolean, 
     isRevealed: boolean 
    }, 
    ... 
    ] 
} 

所以我想要做的是,從game,設置isRevealed爲true,每瓦其中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

它似乎沒有什麼可怕的錯誤,但如果你非常擔心它,只需在映射列表之前使用.withMutations即可。但是,對於非關鍵性代碼中的幾百個對象來說,似乎不值得仔細思考。 – pvg

回答

0

從我的角度來看,該代碼是相當精緻:)然而,有一些小技巧,可能使其更好:

return game.merge({ 
    'isGameOver': true, 
    'tiles': revealedTiles 
}); 
:使用多個 set在同一 Map

可以通過一個merge替代

此外,更新單個瓷磚可以做到更好:

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功能的編程方法。這種方法的好處是,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))