使用javascript中的键将对象数组转换为新的对象数组

Convert an array of object to a new array of object with keys in javscript

我有一个格式如下的对象数组,我想使用 属性 作为键将其转换为一个新的对象数组。密钥应该是唯一的。见下方物体的形状

const mockedList = [
  {
    email: 'aaa@example.com',
    id: '5052',
    name: 'Java',
  },
  {
    email: 'bbb@example.com',
    id: '5053',
    name: 'Python',
  },
  {
    email: 'aaa@example.com',
    id: '5054',
    name: 'C#',
  },
  {
    email: 'bbb@example.com',
    id: '5055',
    name: 'Javascript',
  },
];

我想对此进行转换并获得具有此格式键和值的对象数组。

[
   {
      email: 'bbb@example.com',
      languages: [
         {
            email: 'bbb@example.com',
            id: '5055',
            name: 'Javascript',
         },
         {
            email: 'bbb@example.com',
            id: '5053',
            name: 'Python',
         },
     ]             
   },
   {
      email: 'aaa@example.com',
      languages: [
         {
            email: 'aaa@example.com',
            id: '5052',
            name: 'Java',
         },
        {
            email: 'aaa@example.com',
            id: '5054',
            name: 'C#',
        },
     ]
   }
]

我试过使用 map-reduce

const result = mockedList.reduce((r, a) => {
  r[a.email] = r[a.email] || [];
  r[a.email].push(a);
  return r;
}, Object.create(null));

但是没有得到正确形状的数据

你可以这样做:

const mockedList = [{email: 'aaa@example.com',id: '5052',name: 'Java',},{email: 'bbb@example.com',id: '5053',name: 'Python',},{email: 'aaa@example.com',id: '5054',name: 'C#',},{ email: 'bbb@example.com', id: '5055', name: 'Javascript' },]

const mockedListHash = mockedList.reduce((a, c) => {
  a[c.email] = a[c.email] || { email: c.email, languages: [] }
  a[c.email].languages.push(c)
  return a
}, {})
const result = Object.values(mockedListHash)

console.log(result)

如果您想清除languages内的重复邮件:

const mockedList = [{email: 'aaa@example.com',id: '5052',name: 'Java',},{email: 'bbb@example.com',id: '5053',name: 'Python',},{email: 'aaa@example.com',id: '5054',name: 'C#',},{ email: 'bbb@example.com', id: '5055', name: 'Javascript' },]

const mockedListHash = mockedList.reduce((a, c) => {
  a[c.email] = a[c.email] || { email: c.email, languages: [] }
  a[c.email].languages.push({
    id: c.id,
    name: c.name,
  })
  return a
}, {})
const result = Object.values(mockedListHash)

console.log(result)

这是另一个带有简单 for 循环的选项

// Array
const mockedList = [
  {
    email: 'aaa@example.com',
    id: '5052',
    name: 'Java'
  },
  {
    email: 'bbb@example.com',
    id: '5053',
    name: 'Python'
  },
  {
    email: 'aaa@example.com',
    id: '5054',
    name: 'C#'
  },
  {
    email: 'bbb@example.com',
    id: '5055',
    name: 'Javascript'
  }
];

// Set new object
const newObj = {};

// Use regular loop
for(const el of mockedList) {
  // Use email as key
  // If key already exist, add info
  // to it's languages array
  if(newObj[el.email]) newObj[el.email].languages.push(el);
  else newObj[el.email] = {
    email: el.email,
    languages: [el]
  }
}

// Test
console.log(newObj);

// If you need just array of objects,
// without email as key, then transform it
const newArr = Object.keys(newObj).map((key) => newObj[key]);

// Test
console.log(newArr);