Só uns detalhes pra complementar…
Apesar de ter funcionado, tem um porém (que pode ou não fazer diferença, dependendo do caso) em usar findIndex
: este método sempre percorre o array desde o início, até encontrar o elemento que satisfaça a condição indicada. Isso quer dizer que, dependendo do caso, pode não ser a forma mais eficiente.
No caso de arrays pequenos não vai fazer diferença, afinal, para poucos dados, tudo é rápido. Mas no caso de arrays grandes, já começa a fazer diferença (veja o comparativo no final).
No seu caso, como você quer sobrescrever os valores repetidos (ou seja, pegar sempre a última ocorrência de position
), não precisa ficar verificando toda a hora com findIndex
. Uma alternativa é usar um objeto, usando o position
como chave, e no final pegar somente os valores:
const data = [
{ "position": 1, "id": "" }, { "position": 2, "id": "" }, { "position": 3, "id": "456" },
{ "position": 4, "id": "" }, { "position": 3, "id": "123" }, { "position": 4, "id": "456" }
];
let items = {};
for (let i = 0; i < data.length; i++) {
items[data[i].position] = data[i];
}
items = Object.values(items);
console.log(items);
Assim, se algum elemento tiver o mesmo position
, ele é sobrescrito. No final, o objeto contém apenas uma ocorrência de cada position
, sendo que em caso de repetições, apenas a última ocorrência estará nele. Assim, eu não preciso verificar se o elemento já existe (se não existir, ele é criado, se já existir, ele é sobrescrito).
Por fim, pego somente os valores (usando Object.values
), resultando no array desejado.
Outra forma é usar um Map
, que funciona de maneira similar:
const data = [
{ "position": 1, "id": "" }, { "position": 2, "id": "" }, { "position": 3, "id": "456" },
{ "position": 4, "id": "" }, { "position": 3, "id": "123" }, { "position": 4, "id": "456" }
];
let items = new Map();
for (let i = 0; i < data.length; i++) {
items.set(data[i].position, data[i]);
}
items = Array.from(items.values());
console.log(items);
Comparativo
Como já dito, para arrays pequenos não faz diferença, inclusive neste caso o findIndex
foi até mais rápido (veja aqui o teste).
Mas para arrays grandes, a diferença é brutal, veja aqui como a situação se inverte e as soluções com Object.values
e Map
passam a ser mais rápidas.
Isso acontece provavelmente porque existe um custo inicial para se criar o objeto e o Map
(além de pegar somente os valores no final). Mas conforme o array cresce, este custo se paga e a solução fica muito mais rápida.
Mas como eu já disse, se você só vai ter poucos arrays pequenos, a diferença não será significativa. De qualquer forma, é importante saber que há outras maneiras de resolver, caso um dia você se depare com situações em que os arrays são maiores e a performance seja um ponto crítico.