2016-11-28 49 views
1

這裏有一個簡單的測試,我已經寫了什麼,我想用一個不可變對象添加具有鍵值對的新對象的不可變對象

it('adds a new map with loaded data where the key is the ticker symbol',() => { 
     const state = Map(); 
     const tickers = List.of('AAPL', 'TSLA', 'GOOGL'); 
     const nextState = addTickerKeys(state, tickers); 

     expect(nextState).to.equal(fromJS({ 
      tickers: ['AAPL', 'TSLA', 'GOOGL'], 
      data: { 
       AAPL: {}, 
       TSLA: {}, 
       GOOGL: {} 
      } 
     })); 
    }) 

如何添加數據對象做及對應的鍵與空數據進入狀態對象?

這裏是我到目前爲止已經試過

export function addTickerKeys(state, tickers) { 
    const newState = setTickers(state, tickers); 
    const tickerList = newState.get('tickers'); 
    return tickerList.forEach((value, key, iter) => { 
     return newState.setIn(['data', key]); 
    }) 
} 

我已經試過替代值,鍵和ITER到位回報newState.setIn([「數據」,關鍵])按照文檔( https://facebook.github.io/immutable-js/docs/#/Map/set

然而,我一次比一次相同的響應回,

AssertionError: expected 3 to equal { Object (size, _root, ...) }

有人能向我解釋什麼錯?這似乎是一個足夠簡單的任務,但我似乎正在努力與不可變的對象和TypeScript中的文檔沒有幫助。

回答

1

下面是我剛纔發現的一個簡單答案。

不可變的似乎沒有一個偉大的內置函數用於這個任務,你必須從純函數返回狀態的方式只是令人沮喪。

下面是添加對象鍵值對的一個快速而髒的解決方案。

export function addTickerKeys(state) { 
    const tickerArray = state.get('tickers'); 
    let newState = Map(); 
    for(let i = 0; i < tickerArray.size; i++){ 
     ctr++; 
     newState = state.setIn(['data', tickerArray.get(i)], Map()); 
     state = state.concat(newState); 
     if(i === tickerArray.size - 1){ 
      return state; 
     } 
    } 
} 

如果其他人仍然有不同的答案,更優雅的內置解決方案可能會共享。

1

你的第一個解決方案的快速評論:

就像上Array.prototype本地forEach方法,用於執行在列表中的每個迭代一些副作用不可變列表類型forEach方法。然而,兩者之間的一個細微差別是,回調函數在不可變的forEach上返回false時,它將立即結束循環的執行,而本地forEach是無法執行的。在這裏,你在列表上使用forEach方法,但是返回一個值,這表明你可能將它與map方法混淆在不可變類型和數組上。不幸的是,map不是你正在尋找的。

現在,另一種解決方案:

function addTickerKeys(state, tickers) { 
    return tickers.reduce((acc, ticker) => { 
    return acc.setIn([ 'data', ticker ], Map()); 
    }, Map({ 
    tickers: List(tickers), 
    })) 
}