Подсчёт уникальных элементов массива и их частоты в JavaScript
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Метод reduce
представляет собой надёжный подход для подсчёта количества вхождений элементов в массиве. В объекте count
собираются ключи (элементы массива) и значения (частота их встречаемости):
const fruits = ['apple', 'banana', 'apple'];
const count = fruits.reduce((tally, fruit) => {
tally[fruit] = (tally[fruit] || 0) + 1;
return tally;
}, {});
console.log(count); // { apple: 2, banana: 1 }
Особенности подсчёта количества вхождений
В дата-анализе и визуализации данных возможность эффективного подсчёта количества вхождений элементов в массив может стать решающей. В этом разделе мы разберём различные подходы, оценим их практичность и возможные трудности.
Использование Map для структурированного и современного подсчёта
Объект Map
позволяет повысить структурированность кода и упростить доступ к данным:
const fruits = ['apple', 'banana', 'apple'];
const count = new Map();
fruits.forEach(fruit => count.set(fruit, (count.get(fruit) || 0) + 1));
for (const [key, value] of count.entries()) {
console.log(`${key}: ${value}`);
}
Изолированный подсчёт через reduce и spread
Для предотвращения побочных эффектов, скопируйте массив с использованием оператора spread:
const fruits = ['apple', 'banana', 'apple'];
const count = [...fruits].reduce((tally, fruit) => {
tally[fruit] = (tally[fruit] || 0) + 1;
return tally;
}, {});
Подсчёт в отсортированном массиве
Сначала сгруппируйте одинаковые элементы с использованием sort
, а затем произведите подсчёт. Такой подход упрощает логику и потенциально сокращает временную сложность:
const sortedFruits = ['apple', 'apple', 'banana'].sort();
let previousFruit, frequency = 1;
for (let i = 1; i <= sortedFruits.length; i++) {
if (sortedFruits[i] === previousFruit) {
frequency++;
} else {
if (previousFruit !== undefined) {
console.log(`${previousFruit}: ${frequency}`);
}
previousFruit = sortedFruits[i];
frequency = 1;
}
}
Использование библиотек для упрощения
С помощью lodash
или underscore
можно сократить объём шаблонного кода и улучшить его читаемость. Вот как работает _.countBy
из lodash:
const fruits = ['apple', 'banana', 'apple'];
const count = _.countBy(fruits);
console.log(count); // { apple: 2, banana: 1 }
Визуализация
Представим ключи (уникальные элементы) как разные виды рыб в аквариуме, а значения (частота) означают численность каждого вида рыбы:
Аквариум (Массив): [🐠, 🐟, 🐡, 🐠, 🐟, 🐡, 🐠]
Вот как это выглядит в виде объекта с частотами:
const fishFrequency = {
'🐠': 3,
'🐟': 2,
'🐡': 2
};
Теперь мы видим численность каждого вида рыбы в нашем аквариуме (массиве). 🐠🔢📊
Работа со сложными случаями
Если ваш массив включает в себя не только простые значения, а также объекты или другие массивы, вам понадобится более продвинутый подход к подсчёту частот:
Использование JSON для ключей-объектов
Преобразуйте сложные элементы в строки с помощью JSON.stringify()
:
const arrOfObjects = [{ id: 1 }, { id: 1 }, { id: 2 }];
const count = arrOfObjects.reduce((tally, obj) => {
const key = JSON.stringify(obj);
tally[key] = (tally[key] || 0) + 1;
return tally;
}, {});
console.log(count);
Map для сложных ключей
Для тех, кто предпочитает использование объекта Map
:
const arrOfObjects = [{ id: 1 }, { id: 1 }, { id: 2 }];
const count = new Map();
arrOfObjects.forEach(obj => {
const key = obj.id;
count.set(key, (count.get(key) || 0) + 1);
});
for (const [key, value] of count) {
console.log(`${JSON.stringify(key)}: ${value}`);
}
Возможности работы с данными за пределами подсчета частот
Создав объект частоты или используя Map, вы открываете новые возможности работы с этими данными:
Извлечение уникальных значений
Извлечём уникальные элементы с помощью Object.keys():
const uniqueFruits = Object.keys(count);
console.log(uniqueFruits); // ['apple', 'banana']
Сортировка элементов по частоте
Для выявления наиболее часто встречающихся элементов можно отсортировать их:
const sortedFrequencies = Object.entries(count).sort((a, b) => b[1] – a[1]);
console.log(sortedFrequencies); // [['apple', 2], ['banana', 1]]
Современное итерирование при помощи for...of
Используйте обновлённую конструкцию для итераций:
for (const [fruit, frequency] of Object.entries(count)) {
console.log(`${fruit}: ${frequency}`);
}