[
{x:'Pedro', y:2},
{x:'Lucas', y:3},
{x:'Pedro', y:4}
]
What would be the best filtering that is repeated in the value of X, remaining the one with the highest value in Y?
[
{x:'Pedro', y:2},
{x:'Lucas', y:3},
{x:'Pedro', y:4}
]
What would be the best filtering that is repeated in the value of X, remaining the one with the highest value in Y?
sort
and filter
A very compact solution is to use sort
to sort the values all by name and y
, with the highest y
being the first.
Then use filter
to filter in a way that whenever he picks up a repeated element from the previous element, he discards it. This works because because of sorting, the element you want to keep from repeating is always the first one.
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);
No sort
, when the names are equal with p1.x === p2.x
makes the comparison and returns the one with the highest y
with p2.y - p1.y
. When they are different use name comparison through the localeCompare .
No filter
holds 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 classic for
and add if it does not exist or replace what already exists if you have y
less:
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.
Here's a way to do it:
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);
}