简体   繁体   中英

Javascript remove duplicates from Array of Array of Objects

I want to remove the duplicates from Array of Objects, I tried creating a Set from the Array, using includes and using indexOf, but can get it ok.

class Car{
  constructor(index){
    this.index = index
  }
}

const car1 = new Car(0)
const car2 = new Car(1)
const car3 = new Car(3)

const car4 = new Car(0)
const car5 = new Car(1)
const car6 = new Car(3)

const car7 = new Car(7)
const car8 = new Car(8)
const car9 = new Car(9)


const group1 = [car1, car2, car3]
const group2 = [car4, car5, car6]
const group3 = [car7, car8, car9]

const orders = [group1, group2, group3]

// Using a Set:
const ordersSet = new Set(orders)
console.log(ordersSet)

/*
Set(3) {
  [ Car { index: 0 }, Car { index: 1 }, Car { index: 3 } ],
  [ Car { index: 0 }, Car { index: 1 }, Car { index: 3 } ],
  [ Car { index: 7 }, Car { index: 8 }, Car { index: 9 } ]
}
*/

  // Using includes or using indexOf:

  const uniqueOrders = []

  for (let i = 0; i < orders.length; i++) {
      const newElement =  orders[i]
      if(!uniqueOrders.includes(newElement)){ // Using includes
      //if(uniqueOrders.indexOf(newElement) === -1){ // Using indexOf
          uniqueOrders.push(newElement) 
      }
  }
  console.log(uniqueOrders)

/*
   [
      [ Car { index: 0 }, Car { index: 1 }, Car { index: 3 } ],
      [ Car { index: 0 }, Car { index: 1 }, Car { index: 3 } ],
      [ Car { index: 7 }, Car { index: 8 }, Car { index: 9 } ]
   ]
*/

In my case I would like to get an array with just group1 and group3 or group2 and group3 because group1 is equal to group2:

/*
   [
      [ Car { index: 0 }, Car { index: 1 }, Car { index: 3 } ],
      [ Car { index: 7 }, Car { index: 8 }, Car { index: 9 } ]
   ]
*/

You can use the "filter" array method.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

On second thought... this would be of no use in this case. Because you are trying to filter items through multiple arrays instead of in the same array.

But one thing you're able to do here is use a hashmap to map which car indexes you've already seen...

const uniqueOrders = []
let filter = {}

for (let i = 0; i < orders.length; i++) {
  const carList =  orders[i]  // This would get the whole array of the set and not just the car object
  const uniqueCarList = []
  for (let j = 0; j < carList.length; j++) {
    const car =  carList[j]
    
    if(!filter[car.index]){
      filter[car.index] = true
      uniqueCarList.push(car)
    }
  }

  if(uniqueCarList.length){
    uniqueOrders.push(uniqueCarList)
  }
}

I think this should output what you are expecting or at least helps you get there

you can loop through with reduce to keep track of what is there and only return the data you want

const removeDups = orders.reduce((accumulated, current, index) => {
      const currentMapIds = current.map((car) => car.index);

const isUnique = Object.values(accumulated.currentOrders).reduce((acc, curr) => {
    const unique = currentMapIds.every((car) => curr.indexOf(car) === -1);
    return !acc ? acc : unique;
}, true);
if(isUnique) {
     accumulated.currentOrders[index] = currentMapIds;
   accumulated.orders.push(current);
 }
     return accumulated;
}, {
    currentOrders: {},
    orders: []
});

const uniqueOrders = removeDups.orders;

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