Удалить массив с повторяющимися значениями

У меня есть массив с с массивами, в которых лежат данные о пользователях. Пример:

subarray = [
 ['Ivan', 'Ivanov', 'mail.com', '03.12.1998', 'Moscow Pushkin street', '54681'],
 ['Maxim', 'Maximow', 'testmail.com', '03.11.2000', 'Moscow Pushkin street', '54681'],
 ['Ivan', 'Ivanov', 'mail.com', '03.12.1997', 'Moscow Pushkin street', '54681'],
 ['Danil', 'Danilov', '[email protected]', '02.08.1998', 'Moscow Pushkin street', '54681'],
 ['Vlad', 'Vladov', '[email protected]', '08.4.2010', 'Moscow Pushkin street', '54681']
]

Как мне удалить массив, в котором совпадают имя, фамилия и почта? И если год рождения больше, чем 2003 тоже удалять.. Подскажите, пожалуйста, как это сделать?


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

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

Для текущей задачи удобно представить данные в структуре с ключом, содержащим определенные поля, и значением описывающим сами данные, т.е. словарь Map.

Алгоритм:

  • Перебираем список списков
  • Определяем ключ. Например, для ['Ivan', 'Ivanov', 'mail.com', '03.12.1998', 'Moscow Pushkin street', '54681'] это будет 'Ivan-Ivanov-mail.com'
  • Вытаскиваем год
  • Если данных по ключу нет и при этом год рождения подходящий, то добавляем данные
  • После перебора в словаре будут только подходящие данные

Пример:

function get_user_key(user) {
    return `${user[0]}-${user[1]}-${user[2]}`;
}

subarray = [
    ['Ivan', 'Ivanov', 'mail.com', '03.12.1998', 'Moscow Pushkin street', '54681'],
    ['Maxim', 'Maximow', 'testmail.com', '03.11.2000', 'Moscow Pushkin street', '54681'],
    ['Ivan', 'Ivanov', 'mail.com', '03.12.1997', 'Moscow Pushkin street', '54681'],
    ['Danil', 'Danilov', '[email protected]', '02.08.1998', 'Moscow Pushkin street', '54681'],
    ['Vlad', 'Vladov', '[email protected]', '08.4.2010', 'Moscow Pushkin street', '54681']
];

key_by_user = new Map();
for (user of subarray) {
    key = get_user_key(user);
    year = parseInt(user[3].split('.')[2]);
    
    if (!key_by_user.has(key) && year <= 2003) {
        key_by_user.set(key, user);
    }
}
// console.log([...key_by_user.entries()]);

for (user of key_by_user.values()) {
    console.log(user);
}

→ Ссылка
Автор решения: EzioMercer

Попробуйте так:

const subarray = [
  ['Ivan', 'Ivanov', 'mail.com', '03.12.1998', 'Moscow Pushkin street', '54681'],
  ['Maxim', 'Maximow', 'testmail.com', '03.11.2000', 'Moscow Pushkin street', '54681'],
  ['Ivan', 'Ivanov', 'mail.com', '03.12.1997', 'Moscow Pushkin street', '54681'],
  ['Danil', 'Danilov', '[email protected]', '02.08.1998', 'Moscow Pushkin street', '54681'],
  ['Vlad', 'Vladov', '[email protected]', '08.4.2010', 'Moscow Pushkin street', '54681']
]

const map = new Map();

subarray.forEach(item => {
  const name = item[0];
  const surname = item[1];
  const email = item[2];
  const birthYear = +item[3].split('.')[2];

  const key = `${name}-${surname}-${email}`;

  if (map.has(key) || birthYear > 2003) return;

  map.set(key, item);
});

const filteredSubarray = [...map.values()];

console.log(filteredSubarray);

→ Ссылка
Автор решения: Great Tech

Несколько удивлён, почему уже опубликованные алгоритмы такие громоздкие. Я не думаю, что следует выцеплять каждый элемент каждой записи, slice() то на что дан.

Да и к тому же, говорили ведь в комментариях про фильтрацию) ладно, без неё ещё короче

Моё решение:

  • Создать объект. Как мы знаем, у объекта не может быть двух одинаковых ключей, этим мы и воспользуемся.

  • Пройтись по массиву и запихнуть в объект каждый элемент массива как значение по ключу, который мы скрафтили из первых трёх значений поля (имя, фамилия и почта) с помощью слайса

  • Вывести все значения объекта (на ключи мы забили, они нам были нужны лишь для де-дупликации)

subarray = [
 ['Ivan', 'Ivanov', 'mail.com', '03.12.1998', 'Moscow Pushkin street', '54681'],
 ['Maxim', 'Maximow', 'testmail.com', '03.11.2000', 'Moscow Pushkin street', '54681'],
 ['Ivan', 'Ivanov', 'mail.com', '03.12.1997', 'Moscow Pushkin street', '54681'],
 ['Danil', 'Danilov', '[email protected]', '02.08.1998', 'Moscow Pushkin street', '54681'],
 ['Vlad', 'Vladov', '[email protected]', '08.4.2010', 'Moscow Pushkin street', '54681']
];

obj = {};

subarray.forEach((el) => {
    if(el[3].slice(-4) < 2003)
        obj[el.slice(0,3).join()] = el;
})
   

console.log(Object.values(obj))

→ Ссылка