Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Efficient algorithm for grouping elements and counting duplicates in JavaScript
When working with arrays of objects in JavaScript, you often need to group elements based on shared properties and count duplicates. This is common in data processing tasks like analyzing user activity, inventory management, or survey results.
Problem Overview
Given an array of objects, we want to group them by a specific property and count how many times each group appears. For example, if we have objects with properties like coordinates or identifiers, we can group by the first property and display counts.
Original data: X A B O Y X Z I Y X Z U X A B L Y X Z K Grouped result: Y X Z (3) X A B (2)
Method 1: Counting Property Occurrences
This approach counts how many times each property name appears across all objects:
const arr = [
{x: 'x', acc: 'acc', val: 'val'},
{y: 'y', x: 'x', z: 'z'},
{y: 'y', x: 'x', z: 'z'},
{x: 'x', c: 'c', val: 'val'}
];
const countOccurrence = (arr = []) => {
const res = {};
arr.forEach(item => {
Object.keys(item).forEach(prop => {
(res[prop]) ? res[prop] += 1 : res[prop] = 1;
});
});
return res;
}
const groupByOccurrence = (data = []) => {
const obj = countOccurrence(data);
const res = Object.keys(obj).reduce((acc, val) => {
(acc[obj[val]]) ? acc[obj[val]].push(val) : acc[obj[val]] = [val];
return acc;
}, {});
return res;
}
console.log(groupByOccurrence(arr));
{ '1': [ 'acc', 'c' ], '2': [ 'val', 'y', 'z' ], '4': [ 'x' ] }
Method 2: Grouping by Object Property Values
A more practical approach groups objects by actual property values rather than property names:
const data = [
{type: 'A', category: 'electronics', value: 100},
{type: 'B', category: 'books', value: 20},
{type: 'A', category: 'electronics', value: 150},
{type: 'C', category: 'clothing', value: 75},
{type: 'B', category: 'books', value: 30}
];
const groupByProperty = (arr, property) => {
const grouped = {};
arr.forEach(item => {
const key = item[property];
if (grouped[key]) {
grouped[key].count++;
grouped[key].items.push(item);
} else {
grouped[key] = {
count: 1,
items: [item]
};
}
});
return grouped;
};
// Group by 'type' property
const result = groupByProperty(data, 'type');
console.log(result);
// Display formatted results
Object.keys(result).forEach(key => {
console.log(`${key}: (${result[key].count} items)`);
});
{
A: { count: 2, items: [Object, Object] },
B: { count: 2, items: [Object, Object] },
C: { count: 1, items: [Object] }
}
A: (2 items)
B: (2 items)
C: (1 items)
Method 3: Using reduce() for Concise Grouping
The most efficient approach uses reduce() to group and count in a single pass:
const items = [
{id: 'X', name: 'Product A'},
{id: 'Y', name: 'Product B'},
{id: 'Y', name: 'Product B'},
{id: 'X', name: 'Product A'},
{id: 'Y', name: 'Product B'}
];
const groupAndCount = (arr, key) => {
return arr.reduce((acc, item) => {
const groupKey = item[key];
acc[groupKey] = (acc[groupKey] || 0) + 1;
return acc;
}, {});
};
const counts = groupAndCount(items, 'id');
console.log(counts);
// Format output as requested
Object.entries(counts)
.sort(([,a], [,b]) => b - a) // Sort by count descending
.forEach(([key, count]) => {
const sample = items.find(item => item[key] === key);
console.log(`${key} ${sample.name} (${count})`);
});
{ X: 2, Y: 3 }
Y Product B (3)
X Product A (2)
Comparison
| Method | Use Case | Performance | Complexity |
|---|---|---|---|
| Property Name Counting | Schema analysis | O(n*m) | High |
| Property Value Grouping | Full object grouping | O(n) | Medium |
| reduce() Counting | Simple counting | O(n) | Low |
Conclusion
For efficient grouping and counting, use the reduce() method as it provides the best performance and readability. Choose the property value grouping approach when you need to preserve the original objects along with counts.
