Patrick
Patrick

Reputation: 241

Count and delete duplicates in javascript array

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

Answers (5)

RobG
RobG

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

suman
suman

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

tsh
tsh

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

joeltine
joeltine

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

andrusieczko
andrusieczko

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

Related Questions