Reputation: 241
I have an array of positive integers. Some are unique and some are duplicates. I'm trying to make a function that will count the number of duplicates and pair it with the relevant number.
For instance, if I had this array to start with:
arr = [89, 1, 1, 2, 89, 89];
I'm trying to get this as the result:
res = [
{"id" : 1, "count" : 2 },
{"id" : 2, "count" : 1 },
{"id" : 89, "count" : 3 }
];
This is the function I made up but it doesn't work and I feel like there's a better solution:
function cons_dupes(arr) {
//Consolidate duplicates by deleting everything but one of each.
//Also adds a count of total duplicates with each index.
var out = {};
for (i=0;i<arr.length;i++)
{
if (arr[i] !== 'null')
{
out[i] = {
data: arr[i],
count: 1
};
for (ii=0; ii<arr.length; ii++)
{
if (arr[i]==arr[ii])
{
arr[ii] = 'null';
out[i].count++;
}
}
}
else
{
console.log('null value: arr['+ii+']');
}
}
return out;
}
Any help is greatly appreciated!
Upvotes: 0
Views: 1077
Reputation: 147363
You have "Count and delete duplicates in javascript array" in the subject but you don't mention deleting in the body of the question. You should make sure the question body is complete and does not rely on information in the title, and that the title matches the body.
Most answers here don't delete the duplicates.
Anyhow, assuming that you want a count of members and for duplicates to be removed, you can do the following:
// Removes duplicates from an array and returns an object
// with a count of the members
function removeDupes(arr) {
var result = {};
var i = arr.length;
while (i--) {
// If member is a duplicate, increment count and delete it
if (result.hasOwnProperty(arr[i])) {
result[arr[i]]++;
arr.splice(i, 1);
// Otherwise, just add it to the results
} else {
result[arr[i]] = 1;
}
}
// convert results to the desired object format
return Object.keys(result).map(function (p){return {id: p, count: result[p]};});
}
Upvotes: 1
Reputation: 195
arr = [89, 1, 1, 2, 89, 89];
arr.sort();//it alters the orignal array. so beware
var newArr = [];
var count = 1;
for (i = 0; i<arr.length; i++){
if(arr[i] == arr[i+1]){
count ++;
continue;
} else {
newArr.push({
id: arr[i],
count: count
});
count = 1;
}
}
alert(JSON.stringify(newArr));//newArr holds the data u want
I would do something like this. But there must be better answer
Upvotes: 0
Reputation: 4738
note your for (ii=0; ii<arr.length; ii++)
it is incorrect since you should not count arr[i] == arr[i]
. Change this line to for (ii=i + 1; ii<arr.length; ii++)
will make your function works.
And here is my solution:
function cons_dupes(arr) {
var p = {};
arr.forEach(function (x) { p[x] = (p[x] || 0) + 1; });
return Object.keys(p).map(function (x) { return { id: x, count: p[x] }; });
}
Upvotes: 2
Reputation: 1620
You likely want to do this in two steps: 1) create an object holding the counts of each id, and then 2) create your final array of objects. For example:
var a = [89, 1, 1, 2, 89];
var counts = {};
var final = [];
for (var i = 0; i < a.length; i++) {
if(counts[a[i]] != undefined) {
counts[a[i]] = 1;
} else {
counts[a[i]]++;
}
}
for (var num in counts) {
final.push({'id': num, 'count': counts[num]});
}
// final has what you want here
Upvotes: 4
Reputation: 2824
If you don't mind using http://underscorejs.org/, here's a simple solution:
_.map(_.groupBy(arr), function(value, key) {
return {
id: key,
count: value.length
}
});
Upvotes: 1