如何创建一个没有重复对象的新对象数组? (ES6)

时间:2018-08-23 13:57:47

标签: javascript arrays loops object ecmascript-6

我想从“ 用户”数组创建一个包含所有“ 部门”的数组,在ES6中不要重复。 我已经尝试过forEach,reduce,filter,但没有成功...

用户数组:

let users = [{
    firstname: 'test',
    department: {
      id: 1,
      name: 'hello'
    }
  },
  {
    firstname: 'test2',
    department: {
      id: 2,
      name: 'hello2'
    }
  },
  {
    firstname: 'test2',
    department: {
      id: 1,
      name: 'hello'
    }
  }
]

预期结果:

// Expected 
departments = [{
    id: 1,
    name: 'hello'
  },
  {
    id: 2,
    name: 'hello2'
  }
] */

我的own experiment

let departments = []
users.forEach(user => {
  console.log('-------------------')
  console.log(departments)
  console.log(user)
  console.log(user.department)
  console.log(departments.includes(user.department))

  if (!departments.includes(user.department)) {
    departments.push(user.department)
  }
  console.log(departments)
})

console.log(departments)

感谢您的帮助!

3 个答案:

答案 0 :(得分:4)

问题:

您的问题是您正在检查带有Array#includes()的部门,而该部门更适合与Numberstring之类的原语一起使用,并且无法比较objects,请不要使用它,因为它也与IE不兼容。

解决方案:

您可以使用Array#map()Array#filter()方法进行操作:

var deps = users.map(u => u.department);

let results = deps.filter((item, pos) => {
 return deps.map(v => v.id).indexOf(item.id) == pos;
});
  • 首先map个项目仅保留department对象。
  • 然后filterdepartments排除具有相同id的对象。

演示:

这是一个有效的演示:

let users = [{
    firstname: 'test',
    department: {
      id: 1,
      name: 'hello'
    }
  },
  {
    firstname: 'test2',
    department: {
      id: 2,
      name: 'hello2'
    }
  },
  {
    firstname: 'test2',
    department: {
      id: 1,
      name: 'hello'
    }
  }
];

var deps = users.map(u => u.department);

let results = deps.filter((item, pos) => {
 return deps.map(v => v.id).indexOf(item.id) == pos;
});

console.log(results);

答案 1 :(得分:3)

只需映射到部门,然后根据ID进行过滤:

  const ids = new Set;

 const result = users
   .map(user => user.department)
   .filter(({ id }) => !ids.has(id) && ids.add(id));

(这是O(n),因为设置查找/插入是O(1))

答案 2 :(得分:2)

您可以使用Array.reduce()

let users = [{
    firstname: 'test',
    department: {
      id: 1,
      name: 'hello'
    }
  },
  {
    firstname: 'test2',
    department: {
      id: 2,
      name: 'hello2'
    }
  },
  {
    firstname: 'test2',
    department: {
      id: 1,
      name: 'hello'
    }
  }
];

let departments = users.reduce((acc, obj)=>{
  let exist = acc.find(({id}) => id === obj.department.id);
  if(!exist){
    acc.push({id:obj.department.id, name: obj.department.name});
  }
  return acc;
}, []);
console.log(departments);