最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Counting the occurrences of JavaScript array elements and put in a new 2d array - Stack Overflow

programmeradmin0浏览0评论

Hi I've an array like this

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];

my goal is to count the unique value and have a report about any items on it so the result's well be

Array [
   [5, 3],
   [2, 5],
   [9, 1],
   [4, 1]
]

I found a solution, that can be found in this other post [Counting the occurrences of JavaScript array elements

The @Emissary solution's for me is the best, the problem is that this solution go over and add some new function that I don't need and I can't reply directly to that post to ask how to have only the array that I need :D

@Emissary add the

console.log(key + ': ' + val)

My first idea was, instead console.log I can push every value in 2d array, but I don't think is a good idea, because if I have understand well the @Emissary solutions, the very 1st part of the solution create exactly the array that I need.

Any idea how to "isolate" this particular array?

Hi I've an array like this

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];

my goal is to count the unique value and have a report about any items on it so the result's well be

Array [
   [5, 3],
   [2, 5],
   [9, 1],
   [4, 1]
]

I found a solution, that can be found in this other post [Counting the occurrences of JavaScript array elements

The @Emissary solution's for me is the best, the problem is that this solution go over and add some new function that I don't need and I can't reply directly to that post to ask how to have only the array that I need :D

@Emissary add the

console.log(key + ': ' + val)

My first idea was, instead console.log I can push every value in 2d array, but I don't think is a good idea, because if I have understand well the @Emissary solutions, the very 1st part of the solution create exactly the array that I need.

Any idea how to "isolate" this particular array?

Share Improve this question edited May 23, 2017 at 12:07 CommunityBot 11 silver badge asked Nov 17, 2016 at 21:42 Jorman FranziniJorman Franzini 3391 gold badge3 silver badges19 bronze badges
Add a ment  | 

7 Answers 7

Reset to default 5

This is an ideal situation to use a Map because it identifies by key, but also turns into that type of array when cast to it:

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];

var result = [...a.reduce( (m, v) => m.set(v, (m.get(v) || 0) + 1), new Map() )];

console.log(result);

Note that solutions which perform a.filter on every iteration, have O(n²) time plexity, while this is O(n). Instead of the spread operator you can use Array.from(a.reduce(....)).

For older browsers you can use this variant:

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];

var obj = a.reduce( function (m, v) { return m[v] = (m[v] || 0) + 1, m }, {} ),
    result = [];
for (var key in obj) {
    result.push([+key, obj[key]]);
}
console.log(result);

You can do this with forEach() loop.

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];

var result = []
a.forEach(function(e) {
  if (!this[e]) {
    this[e] = [e, 0];
    result.push(this[e])
  }
  this[e][1] ++
}, {})

console.log(result)

You can do it using Mapmap of ES6 and Convert it back into array using Array.from array.from

Map is similar like hash,which maintains a key value pair. Instead of traversing each element and maintaining a count,create a map and set the count of each occurrence and convert it to an array which is easy with es6

check this snippet

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
var myMap2 = new Map();
a.forEach(function(num) {
  if (myMap2.has(num)) {
    var count = myMap2.get(num);
    myMap2.set(num, count + 1);
  } else
    myMap2.set(num, 1);
});

var arr = Array.from(myMap2);
console.log(arr);

Hope it helps

Just pull it out of the Map constructor

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
var aCount = [...new Set(a)].map(
  x => [x, a.filter(y => y === x).length]
);
console.log(aCount);
   

You could use the spread syntax with the solution of Emissary to get the an array with the wanted result.

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];

var aCount = [... new Map([... new Set(a)].map(
    x => [x, a.filter(y => y === x).length]
))];
              
console.log(aCount);

It's interesting to note that the reduce and spread syntax solution is also very efficient when evaluating array of words occurrences/frequency in a text (typically bag of words) when bined with the map to transform the output columns:

var r,words="We don't talk anymore\nWe don't talk anymore\nWe don't talk anymore\nLike we used to do\nWe don't love anymore\nWhat was all of it for?\nOh, we don't talk anymore\nLike we used to do\n\nI just heard you found the one you've been looking\nYou've been looking for"
words=words.split(/['\s]+/g);
r=[...words.reduce( (m, v) => m.set(v, ((m.get(v) || 0) + 1)), new Map() )].map(e=>[e[0],e[1]/words.length])
console.log(r)

Good solutions here but just for variety you might as well do as follows while getting your results sorted

var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4],
thing = a.reduce((p,c) => (p[c] ? p[c]++ : p[c] = 1,p),[])
         .reduce((p,c,i) => c ? (p.push([i,c]),p) : p ,[]);
console.log(thing);

Ok... and one might plain about the possibility of generating a huge sparse array depending on the original numbers but hey no worries... The for in loop takes care of that. So lets do it again...

var  a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4],
sparse = a.reduce((p,c) => (p[c] ? p[c]++ : p[c] = 1,p),[]),
 dense = [];
for (var key in sparse) dense.push([+key,sparse[key]]);
console.log(dense);

发布评论

评论列表(0)

  1. 暂无评论