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)