Home > other >  How to filter duplicate id products taking in consideration other property using Javascript?
How to filter duplicate id products taking in consideration other property using Javascript?

Time:06-14

I have a product array that I receive with some combinations.

Each combination can also have multiple combinations so in the array I receive all posibilities of every combination. I have a select in which I want to show all different posibilities and select by default the combination marked as default, but I do not want to show duplicate values.

I give an example:

[
 {'id_combination': 15, 'default': false, ....},
 {'id_combination': 20, 'default': false, ....},
 {'id_combination': 30, 'default': false, ....},
 {'id_combination': 30, 'default': true, ....},
 {'id_combination': 45, 'default': false, ....},
 ...
]

What I would like to get is another array that will be like this (just removing duplicate elements - with same id_combination - that does not have default:true value).

[
 {'id_combination': 15, 'default': false, ....},
 {'id_combination': 20, 'default': false, ....},
 {'id_combination': 30, 'default': true, ....},
 {'id_combination': 45, 'default': false, ....},
 ...
]

I have tried using map, filter, sort... but I cannot figure out how to achieve this.

I have to mention that the data that I receive from the back cannot be changed (as I do not have control about it).

How can I filter this array removing duplicated id_combination that does not have default property set to true?

Note that if I have duplicated elements and none of them are set to default I also want to show at least one of them on the select (though they will not be selected by default).

Thanks in advance!

CodePudding user response:

test = [
 {'id_combination': 15, 'default': false,},
 {'id_combination': 20, 'default': false,},
 {'id_combination': 30, 'default': false,},
 {'id_combination': 30, 'default': true,},
 {'id_combination': 45, 'default': false},
 {'id_combination': 45, 'default': true},
 {'id_combination': 45, 'default': false},
 {'id_combination': 45, 'default': false},
]

// sort by "id_combination" in ascending, and then by their "default" where  `false` first, then `true` second
sorted_test = test.sort((a, b) => {
    return a["id_combination"] - b["id_combination"] || (a["default"] && !b["default"])
})


unique = [...new Map(sorted_test.map(item => [item["id_combination"], item])).values()]
console.log(unique)

Result:

[ { id_combination: 15, default: false },
  { id_combination: 20, default: false },
  { id_combination: 30, default: true },
  { id_combination: 45, default: true } ]

Algorithm:

Sort them by their id_combination in ascending order, and also in their default key where false first, then true second.

Then, using map, it will eliminate duplicate key values where it only keep the last value inserted (which contains the default true if there is any).

PS: Sorry, my English is bad

CodePudding user response:

You can filtered out the duplicates with the help of Array.filter() method along with .indexOf() and .lastIndexOf()

Demo :

// Input array
const arr = [
 {'id_combination': 15, 'default': false},
 {'id_combination': 20, 'default': false},
 {'id_combination': 30, 'default': false},
 {'id_combination': 30, 'default': true},
 {'id_combination': 45, 'default': false}
];

// creating an array which contains the 'id_combinations' property value coming from Input array.
const combinationIds = arr.map(obj => obj.id_combination);

// Filtering out the results with the help of .indexOf() and .lastIndexOf() 
const res = arr.filter(obj => (combinationIds.indexOf(obj.id_combination) === combinationIds.lastIndexOf(obj.id_combination)) || obj.default)

console.log(res)

  • Related