如何从条目具有密钥ID的对象数组中创建{id:value,...}之类的对象?

时间:2016-12-28 17:50:49

标签: javascript ecmascript-6

我疯狂地试图净化这个脏const initialState的这个函数!

const getInitialState = (entries) => {
  const initialState = {}
  entries.map(entry => initialState[entry.id] = 1)
  return initialState
}

我得到的输出,预计是

const obj = {
  1: 1,
  2: 1,
  3: 1,
}

谢谢!

澄清

遗漏了一点,在上面编辑过。

我最终减少了

const getInitialState = entries =>
  entries.reduce((initialState, entry) => ({
    ...initialState,
    [entry.id]: 1,
  }), {})

还关注这里缺乏幽默和指责“咒骂”?

2 个答案:

答案 0 :(得分:1)

如果您实际将属性分配给initialState,那么您的第一个代码段就可以正常工作,例如entries.map(entry => initialState[entry.id] = 1)。另外:在这种情况下,使用forEach代替map会更有意义。

除此之外,您还可以使用Array.prototype.reduceObject.assign将数组缩小为单个对象。

我让这个例子有点冗长,以便更容易理解。



// I assume that your array looks something like this?
const data = [ { 'id': 1 }, { 'id': 2 }, { 'id': 3 }, { 'id': 4 } ];

const getInitialState = entries => {
  return entries.reduce((obj, entry) => {
    return Object.assign(obj, { [entry.id]: 1 });
  }, { });
};

console.log(getInitialState(data));




答案 1 :(得分:0)

  

试图净化这个脏const的这个函数

我认为你对此有点过于教条。

除此之外,map()是正确的方法,因为a)它会创建一个额外的数组,你不会使用,因为你只使用地图来迭代,而b)无论如何它和&# #39;仅在阵列上可用。

如果b点没问题,您应该使用forEach进行迭代,或者使用 Felix Kling 评论中的reduce

但是由于ES6引入了一种可迭代的表面,你可以通过手动循环使这个函数处理任何可迭代的结构:

const getInitialState = (list) => {
    const initialState = {};
    for(let entry of list)
        initialState[entry.id] = 1;
    return initialState;
}

但我推荐两项改进措施:

  • 而不是对象,请使用const initialState = Object.create(null); 这样,initialState甚至不会从Object继承,你可以确定该对象上的每个键都是自己的,无论如何。

  • getInitialState已经非常具体了,为什么不让它更通用,更有用于其他目的

    const mapById = (list) => {
        const mapping = Object.create(null);
        for(let entry of list) 
            mapping[entry.id] = entry;
        return mapping;
    }
    

    这样你仍然可以通过这个特定的ID(例如:if(entriesById[someId]){ ... })查看那里的对象,你还有一个快捷方式来按ID获取条目;比为您可能想要获得的每个ID迭代列表更快。