Удалить массив с повторяющимися значениями
У меня есть массив с с массивами, в которых лежат данные о пользователях. Пример:
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 шт):
Для текущей задачи удобно представить данные в структуре с ключом, содержащим определенные поля, и значением описывающим сами данные, т.е. словарь 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);
}
Попробуйте так:
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);
Несколько удивлён, почему уже опубликованные алгоритмы такие громоздкие. Я не думаю, что следует выцеплять каждый элемент каждой записи, 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))