将对象中的键映射到发生的键

时间:2019-10-22 20:29:28

标签: javascript node.js object

我有以下对象:

[{animal: 1, hasLegs: true},{animal: 1, hasTail: false},
 {animal: 2, hasLegs: true},{animal: 2, hasTail: true},{animal: 3}]

我想将其重组为以下内容:

[
  { animal:1, info: { hasLegs: true, hasTail: false },
  { animal:2, info: { hasLegs: true, hasTail: true },
  { animal:3, into: {},
]

使得具有animal:1的数组中的所有对象统一在该键下,并在键info下将其余键与值相加。

曾经尝试使用map()函数但无法掌握其功能,并且不知道单独使用map()是否可以解决此问题。

3 个答案:

答案 0 :(得分:2)

这是一个相似的答案,但应具有更好的性能,因为它利用了映射哈希的优势,而不是对每个条目进行查找。

const data = [{animal: 1, hasLegs: true},{animal: 1, hasTail: false},
  {animal: 2, hasLegs: true},{animal: 2, hasTail: true},{animal: 3}]

const infoMap = data.reduce((rollup, { animal, ...info }) => {
  const entry = rollup[animal] = rollup[animal] || {}
  Object.assign(entry, info)
  return rollup
}, {})

const result = Object.keys(infoMap)
  .map((animal) => ({
    animal,
    info: infoMap[animal]
  }))

console.log(result)

答案 1 :(得分:2)

我建议从初始数组创建一个查找对象。这样,您无需遍历每个元素上的整个数组(这将使它O(n²))。

所以预先给出了我们的列表:

const animals = [
  { animal: 1, hasLegs: true },
  { animal: 1, hasTail: false },
  { animal: 2, hasLegs: true },
  { animal: 2, hasTail: true },
  { animal: 3 }
]

我们用reduce创建一个查找表,将在原始数组中找到的每个对象合并到动物的value对象中:

const lookup = animals.reduce((acc, val) => {
  // use object destructuring and object spread to pick out
  // the "animal" field and the rest into separate variables
  const { animal, ...info } = val
  // get existing info object, or create new empty if not found
  const existingInfo = acc[animal] || {}
  // merge existing info and new info from this object
  acc[animal] = { ...existingInfo, ...info }
  return acc
}, {})

此时,结构如下:

{
  '1': { hasLegs: true, hasTail: false },
  '2': { hasLegs: true, hasTail: true },
  '3': {}
}

现在,我们只需要遍历此对象并将其转换为数组,然后将键选择到“动物”字段中即可:

const after = Object.entries(lookup).map(([key, value]) => {
  return { animal: key, info: value }
})

这将产生我们想要的结果:

[
  { animal: '1', info: { hasLegs: true, hasTail: false } },
  { animal: '2', info: { hasLegs: true, hasTail: true } },
  { animal: '3', info: {} }
]

请注意,尽管较旧的浏览器可能不支持Object.entries。如果您定位的是较旧的浏览器,请在Object.keys

的答案中查看Robb Traister的工作方式

答案 2 :(得分:1)

const array = [{ animal: 1, hasLegs: true }, { animal: 1, hasTail: false },
{ animal: 2, hasLegs: true }, { animal: 2, hasTail: true }, { animal: 3 }];
const result = [];
array.forEach(obj => {
    let newEntry = null;
    if (result.findIndex(entry => entry.animal === obj.animal) === -1) {
        newEntry = { animal: obj.animal, info: {} }
        result.push(newEntry);
    }
    const entry = newEntry || result.find(entry => entry.animal === obj.animal);
    Object.keys(obj).forEach(key => {
        if (key === 'animal') return;
        entry.info[key] = obj[key];
    });

});
console.log(result);