2016-11-28 50 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), 
    })) 
}