Выборка только уникальных значений из подмассивов массива

Есть массив такого вида:

[
    [1,"Porsche 911",{"id":1,"section":1,"tag":"Cars"}],
    [2,"Porsche 911",{"id":1,"section":1,"tag":"Parts"}],
    [2,"Toyota Corolla",{"id":1,"section":1,"tag":"Parts"}]
]

Мне нужно получить массив, в котором будут только уникальные имена машин, без id тегов и прочего. Я делаю так:

function onlyUnique(value, index, self) {
    return self.indexOf(value) === index;
}

unicCars = cars.filter(onlyUnique);

Если скармливать мой массив этой функции, она считает все поля разными, т.к. сравнивает не только имена машин. Я понадеялся, что если подсказать что сравнивать нужно только значения по ключу value[1] - то будет то что нужно!

function onlyUnique(value, index, self) {
    return self.indexOf(value[1]) === index;
}

Но так не работает. Как всё-таки получить уникальные имена?


Ответы (1 шт):

Автор решения: Regent

Вариант с value[1] не работает, потому что value[1] при этом сравнивается с другими элементами массива (value), а не с "под-элементами" (value[1])

C заранее сформированным массивом имён машин (value[1]) первоначальный вариант будет работать:

let cars = [
    [1,"Porsche 911",{"id":1,"section":1,"tag":"Cars"}],
    [2,"Porsche 911",{"id":1,"section":1,"tag":"Parts"}],
    [2,"Toyota Corolla",{"id":1,"section":1,"tag":"Parts"}]
];

let carNames = cars.map(car => car[1]);

function onlyUnique(value, index, self) {
  return self.indexOf(value) === index;
}

let uniqueCarNames = carNames.filter(onlyUnique);
console.log(uniqueCarNames);

Данное решение работает за O(n^2), поэтому для больших массивов стоит попробовать что-то более быстро работающее. Например, Set (или реализовать аналогичную логику вручную, если нужна поддержка IE):

let cars = [
    [1,"Porsche 911",{"id":1,"section":1,"tag":"Cars"}],
    [2,"Porsche 911",{"id":1,"section":1,"tag":"Parts"}],
    [2,"Toyota Corolla",{"id":1,"section":1,"tag":"Parts"}]
];

let carNames = cars.map(car => car[1]);
let uniqueCarNames = [...new Set(carNames)];
console.log(uniqueCarNames);

→ Ссылка