1

Hey i have a simple question i cant find an answer, i´m trying to generate some raw-data for a chart

lets say i have an array like :

[1,0,0,1,2,0]

is there a way to make an array out of it that has nested arrays that represent the count of duplicate entrys ?

[[0,3],[1,2],[2,1]]

here is some code that does the trick, but saves the count as objects

var array = [1,0,0,1,2,0];
var length = array.length;
var objectCounter = {};

for (i = 0; i < length; i++) {

    var currentMemboerOfArrayKey = JSON.stringify(array[i]);

    var currentMemboerOfArrayValue = array[i];

    if (objectCounter[currentMemboerOfArrayKey] === undefined){

         objectCounter[currentMemboerOfArrayKey] = 1;
    }else{
        objectCounter[currentMemboerOfArrayKey]++;
    }
}

but objectCounter returns them like

{0:3,1:2,2:1}

but i need it as an array i specified above ?

for any help, thanks in advance

1
  • 1
    You can just convert it to an array with a forin loop. Or initialize with Array() Commented Dec 16, 2013 at 9:30

6 Answers 6

3

Try

var array = [1, 0, 0, 1, 2, 0];

function counter(array) {
    var counter = [],
        map = {}, length = array.length;
    $.each(array, function (i, val) {
        var arr = map[val];
        if (!arr) {
            map[val] = arr = [val, 0];
            counter.push(arr);
        }
        arr[1] += 1;
    })

    return counter;
}
console.log(JSON.stringify(counter(array)))

Demo: Fiddle

Sign up to request clarification or add additional context in comments.

2 Comments

Yeah that for me is the perfect solution ! thank you very much and the others too
Could you explain how this code works? I think it is quite interesting how you link map[val] and arr to the same array and how you've taken advantage of the closure to store the map variable.
2

You can turn your object into an array easily:

var obj = {0:3,1:2,2:1};

var arr = [];
for (var key in obj) {
  // optional check against Object.prototype changes
  if (obj.hasOwnProperty(key)) {
    arr.push([+key, obj[key]]);
  }
}

Note: The object keys are strings, so i converted them back to numbers when placed in the array.

Comments

2

Functional way of doing this, with Array.reduce and Array.map

var data = [1,0,0,1,2,0];

var result = data.reduce(function(counts, current) {
    counts[current] = current in counts ? counts[current] + 1: 1;
    return counts;
}, {});

result = Object.keys(result).map(function(current){
    return [parseInt(current), result[current]];
});
console.log(result);

Output

[ [ 0, 3 ], [ 1, 2 ], [ 2, 1 ] ]

2 Comments

Nice elegant, functional solution! How could I adapt it to work on, for example, an array of letters?
@i_made_that What do you want as the output?
1

Try:

var data = [1,0,0,1,2,0];
var len = data.length;
var ndata = [];
for(var i=0;i<len;i++){
    var count = 0;
    for(var j=i+1;j<len;j++){
        if(data[i] == data[i]){
            count ++;
        }
    }
    var a = [];
    a.push(data[i]);
    a.push(count);
    ndata.push(a);   
}
console.log(ndata)

DEMO here.

Comments

1

First you need to map the array to an associative object

var arr = [1,0,0,1,2,0];
var obj = {};
for (var i = 0; i < arr.length; i++) {
  if (obj[arr[i]] == undefined) {
    obj[arr[i]] = 0;
  }
  obj[arr[i]] += 1;
}

Then you can easily turn that object into a 2d matrix like so:

arr = [];
for (var k in obj) {
  arr.push([k, obj[k]]);
}

alert(JSON.stringify(arr));

Comments

1

Your existing object can be turned into an array with a simple for..in loop. Also your existing code that produces that object can be simplified. Encapsulate both parts in a function and you get something like this:

function countArrayValues(array) {
  var counter = {},
      result = [];

  for (var i = 0, len = array.length; i < len; i++)
    if (array[i] in counter)
      counter[array[i]]++;
    else
      counter[array[i]] = 1;

  for (i in counter)
    result.push([+i, counter[i]]);

  return result;
}

console.log( countArrayValues([1,0,0,1,2,0]) );

Demo: http://jsfiddle.net/hxRz2/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.