简体   繁体   English

在数组上映射后创建动态对象键

[英]Creating Dynamic Object Keys After mapping on an Array

So I want to create a quite complex data structure that looks like the following:所以我想创建一个非常复杂的数据结构,如下所示:

slots: {
    'slot_1': {
         id: 'slot_1',
         associatedCard: {}
         },
    'slot_2': {
         id: 'slot_2',
         associatedCard: {}
         },
    'slot_3': {
         id: 'slot_3',
         associatedCard: {}
         }
}

I have 10 slots that I want to populate with cards (each slot can contain one card) so I am actually looping over the cards, creating the slots and I tried to dynamically generate the above data structure.我有 10 个插槽,我想用卡片填充(每个插槽可以包含一张卡片),所以我实际上是在卡片上循环,创建插槽,并尝试动态生成上述数据结构。 Here is my code:这是我的代码:

 slots: (() => {
        return {
            ...cards.map((card, index) => {
            return {
                            [`slot_${index + 1}`]: {
                                id: `slot_${index + 1}`,
                                ownedCard: {}
                            }
                        };
                    })
                };
            })(),

However, I am not getting what I desire.然而,我没有得到我想要的。 This is what I get:这就是我得到的: 在此处输入图片说明

How can I fix this so that I have slot_1 instead of 0 as key, slot_2 instead of 1 as key, etc..?我该如何解决这个问题,以便我将 slot_1 而不是 0 作为键,将 slot_2 而不是 1 作为键,等等......?

The problem is that map returns an array, which is why you are getting numbered keys.问题是map返回一个数组,这就是为什么你得到编号的键。 You need to do something like:您需要执行以下操作:

const slots = cards.reduce((obj, card, index) => {
  const id = `slot_${index + 1}`
  obj[id] = {
    id,
    associatedCard: card
  }
  return obj
}, {})

Don't Array#map the items, Array#reduce them, instead:不要Array#map项目, Array#reduce它们,而是:

cards.reduce((acc, card, index) => {
    return { ...acc,
            [`slot_${index + 1}`]: {
                id: `slot_${index + 1}`,
                ownedCard: {}
            }
        };
    }, {})

The .map method will produce an array of new items based on the old ones. .map方法将根据旧项生成一新项。 And since you return an object, you get an array of objects.并且由于您返回一个对象,因此您将获得一个对象数组。 Yet, what you want is one object that has all those keys.然而,您想要的是一个拥有所有这些键的对象。 The .reduce method is more advanced (as in, can do more stuff) and it turns an array into "one value" -> hence reduce . .reduce方法更高级(例如,可以做更多的事情),它将数组转换为“一个值” -> 因此reduce Your desired value is a single object, so you can just combine each of them.您想要的值是单个对象,因此您可以将它们中的每一个组合起来。

An alternative to using the spread notation is to use Object.assign and re-use the same object instead of doing a clone every time:使用扩展符号的另一种方法是使用Object.assign并重新使用相同的对象,而不是每次都进行克隆:

cards.reduce((acc, card, index) => {
    return Object.assign{acc, {
            [`slot_${index + 1}`]: {
                id: `slot_${index + 1}`,
                ownedCard: {}
            }}
        };
    }, {});

If you do want to keep the .map , then you can still chain that into .reduce :如果您确实想保留.map ,那么您仍然可以将其链接到.reduce

cards.map((card, index) => {
    return {
            [`slot_${index + 1}`]: {
                id: `slot_${index + 1}`,
                ownedCard: {}
            }
        };
})
.reduce((acc, obj) => ({...acc, ...obj}));

or或者

cards.map((card, index) => {
    return {
            [`slot_${index + 1}`]: {
                id: `slot_${index + 1}`,
                ownedCard: {}
            }
        };
})
.reduce((acc, obj) => Object.assign(acc, obj), {});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM