简体   繁体   中英

Removing duplicates and filtering based on a boolean property from array of objects in JavaScript

I have two array of objects with these properties:

const a = [{name: 'Anna',email: 'anna@mac.com',flag: false},
  {name: 'Kelly',email: 'kelly@mac.com',flag: true}];
const b = [{name: 'Rana',email: 'rana@mac.com',flag: true},
  {name: 'Anna',email: 'anna@mac.com',flag: true},
  {name: 'Hank',email: 'Hank@mac.com',flag: false}];

I want to remove all the duplicates containing the flag of false value but both duplicates have flag of false then I just want to keep one of them. But if any object doesn't have any duplicates then I want to keep it regardless of it's flag property. I tried this to remove duplicates but couldn't filter by the flag property.

let cs = a.concat(b);
   cs = cs.filter((c, index, self) => 
index === self.findIndex((t) => (
    t.email === c.email  
))

Expected output would be like this:

[{"name":"Anna","email":"anna@mac.com","flag":true},
{"name":"Kelly","email":"kelly@mac.com","flag":true}, 
{"name":"Rana","email":"rana@mac.com","flag":true},
{"name":"Hank","email":"Hank@mac.com","flag":false}]

See Map , Array.prototype.map() , and Array.prototype.filter() for more info.

 // A. const A = [{name: 'Anna',email: 'anna@mac.com',flag: false}, {name: 'Kelly',email: 'kelly@mac.com',flag: true}] // B. const B = [{name: 'Rana',email: 'rana@mac.com',flag: true}, {name: 'Anna',email: 'anna@mac.com',flag: true}, {name: 'Hank',email: 'Hank@mac.com',flag: false}] // Unique Users. const uniqueUsers = (...arrays) => [...new Map([].concat.apply([], arrays).map(user => [user.email.toLowerCase(), user])).values()] // Proof. const C = uniqueUsers(A, B) console.log(C) // Optional Filtration By Flag. const D = C.filter(user => user.flag) 

It seems that you already know that a doesn't contain duplicates and b doesn't contain duplicates. So you can use

const a = [{name: 'Anna',email: 'anna@mac.com',flag: false},
  {name: 'Kelly',email: 'kelly@mac.com',flag: true}];
const b = [{name: 'Rana',email: 'rana@mac.com',flag: true},
  {name: 'Anna',email: 'anna@mac.com',flag: true},
  {name: 'Hank',email: 'Hank@mac.com',flag: false}];

const map = new Map();
for (const o of a) {
  map.set(o.email, o);
}
for (const o of b) {
  if (!map.has(o.email) || !map.get(o.email).flag)
    map.set(o.email, o);
  // else keep the one from a
}
return Array.from(map.values());

Another approach using reduce :

 const a = [{name: 'Anna',email: 'anna@mac.com',flag: false}, {name: 'Kelly',email: 'kelly@mac.com',flag: true}]; const b = [{name: 'Rana',email: 'rana@mac.com',flag: true}, {name: 'Anna',email: 'anna@mac.com',flag: true}, {name: 'Hank',email: 'Hank@mac.com',flag: false}]; let resp = [].concat(a, b) .reduce((acc, { name, email, flag }) => { if(!flag || acc.some(x => x.name == name && x.email == email)) return acc; return acc.concat({name, email, flag}); }, []) console.log(resp); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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