1
[
{x:'Pedro', y:2},
{x:'Lucas', y:3},
{x:'Pedro', y:4}
]
Which would be the best filter that repeats at the value of X, remaining the one with the highest value in Y?
1
[
{x:'Pedro', y:2},
{x:'Lucas', y:3},
{x:'Pedro', y:4}
]
Which would be the best filter that repeats at the value of X, remaining the one with the highest value in Y?
2
sort
and filter
A very compact solution is to use sort
to sort all values by name and y
, getting the bigger ones y
first.
Then uses filter
to filter so that whenever it picks up an element repeated to the previous one, it discards it. This works because due to ordering, the element you want to keep from repeaters is always the first.
Implementation:
let pessoas = [
{x:'Pedro', y:2},
{x:'Lucas', y:3},
{x:'Pedro', y:4}
];
pessoas.sort((p1,p2) => p1.x === p2.x ? p2.y - p1.y : p1.x.localeCompare(p2.x));
let filtradas = pessoas.filter((el, idx) => idx === 0 || pessoas[idx - 1].x !== el.x);
console.log(filtradas);
In the sort
, when the names are equal with p1.x === p2.x
makes the comparison and returns what has larger y
with p2.y - p1.y
. When different uses the comparison of names through the locationCompare.
In the filter
keeps the value if it is the first with idx === 0
, or if the name is different from the previous one: pessoas[idx - 1].x !== el.x
.
for
classic and findIndex
You can also opt for a traditional solution with a for
classic and add if there is no or replace the one that already exists if you have a y
minor:
let pessoas = [
{x:'Pedro', y:2},
{x:'Lucas', y:3},
{x:'Pedro', y:4}
];
let filtradas = [];
for (let i = 0; i < pessoas.length; ++i){
let posPessoa = filtradas.findIndex(p => pessoas[i].x === p.x);
if (posPessoa === -1){ //não existe
filtradas.push(pessoas[i]); //adiciona
}
else if (filtradas[posPessoa].y < pessoas[i].y){ //existe e tem y menor
filtradas[posPessoa] = pessoas[i]; //substitui pela de y maior
}
}
console.log(filtradas);
In this solution the only native function I used was findIndex to find the position of the person with the same name in the array. This returns -1
if the element does not exist in the array.
0
Follow a way of doing:
function removeDuplicates(myArr, prop) {
return myArr.filter((obj, pos, arr) => {
return arr.map(mapObj => mapObj[prop]).indexOf(obj[prop]) === pos;
});
};
var lista = [
{ x: 'Pedro', y: 2 },
{ x: 'Lucas', y: 3 },
{ x: 'Pedro', y: 4 }
];
var listaX = removeDuplicates(lista, "x");
for (i = 0; i < listaX.length; i++) {
var max = Math.max.apply(Math, lista.filter(function (e) { return e.x == listaX[i].x; }).map(function (o) { return o.y; }));
var maxObj = lista.filter(function (e) { return e.x == listaX[i].x && e.y == max; });
console.log(maxObj);
}
References: https://ilikekillnerds.com/2016/05/removing-duplicate-objects-array-property-name-javascript/ https://stackoverflow.com/questions/4020796/finding-the-max-value-of-an-attribute-in-an-array-of-objects
Browser other questions tagged javascript
You are not signed in. Login or sign up in order to post.