How do I get an array of counters of specific objects in an existing array?

I have an array of objects like this:

[
  {
    importantKey: 'x',
    foo: 'bar',
    ...
  },
  {
    importantKey: 'y',
    foo: 'bar',
    ...
  },
  {
    importantKey: 'z',
    foo: 'bar',
    ...
  },
  {
    importantKey: 'x',
    foo: 'bar',
    ...
  },
  {
    importantKey: 'y',
    foo: 'bar',
    ...
  },
  {
    importantKey: 'z',
    foo: 'bar',
    ...
  },
  ...
]

      

And another array that has values importantKey

:

keysArray = [x, y, z]

      

How do I get an array with values ​​that are counts of all objects having each importantKey

in the same order as keysArray

? So the end result will be:

[ numberOfObjectsWithKeyX, numberOfObjectsWithKeyY, numberOfObjectsWithKeyZ ]

      

In this example, the result would be:

[2, 2, 2]

      

Also keysArray

dynamically generated, therefore x

, y

and z

cannot be hardcoded.

+3


source to share


4 answers


You can do something like this:

keysArray.map(key => values.filter(v => v.importantKey === key).length);

      

Basically, you call map()

in keysArray

, which will create a parallel array for it with any values map()

.



For that value, you only call values.filter()

and filter things that have a matching key, and then just check the length to get the count.

const values = [
  {
    importantKey: 'x',
    foo: 'bar'
  },
  {
    importantKey: 'y',
    foo: 'bar'
  },
  {
    importantKey: 'y',
    foo: 'bar'
  },
  {
    importantKey: 'x',
    foo: 'bar'
  },
  {
    importantKey: 'y',
    foo: 'bar'
  },
  {
    importantKey: 'z',
    foo: 'bar'
  }
];

const keys = ['x', 'y', 'z'];

const result = keys.map(key => values.filter(v => v.importantKey === key).length);

console.log(result);
      

Run codeHide result


+2


source


Using the Array function map

and then filter

.

Function

map

converts an array to another array. The function filter

allows you to filter an array with a given predicate. In this case, you need to compare the value importantKey

.



var arr1 = [
  {
    importantKey: 'x',
    foo: 'bar',
    
  },
  {
    importantKey: 'y',
    foo: 'bar',
    
  },
  {
    importantKey: 'z',
    foo: 'bar',
    
  },
  {
    importantKey: 'x',
    foo: 'bar',
    
  },
  {
    importantKey: 'y',
    foo: 'bar',
    
  },
  {
    importantKey: 'z',
    foo: 'bar',
    
  },
  {
    importantKey: 'x',
    foo: 'bar',
    
  }
 
];

var keysArray = ['x', 'y', 'z']
console.log(keysArray.map(a => arr1.filter(b=>b.importantKey == a).length));
      

Run codeHide result


+2


source


You can use a hash table as an index reference for an array of results.

This proposal uses a slingle loop to iterate over the data.

var data = [{ importantKey: 'x', foo: 'bar' }, { importantKey: 'y', foo: 'bar' }, { importantKey: 'z', foo: 'bar' }, { importantKey: 'x', foo: 'bar' }, { importantKey: 'y', foo: 'bar' }, { importantKey: 'z', foo: 'bar' }],
    keysArray = ['x', 'y', 'z'],
    hash = Object.create(null),
    result = keysArray.map(function (k, i) { hash[k] = i; return 0; });

data.forEach(function (o) {
    result[hash[o.importantKey]]++;
});

console.log(result);
      

Run codeHide result


+1


source


Easy understanding of the solution.

  • Read data

  • Paste in map

  • Iterating through map

  • Insert into array k

    ok[x,y,z]

var data = 
[
  {importantKey: 'z', foo: 'bar' },
  {importantKey: 'y', foo: 'bar' },
  {importantKey: 'z', foo: 'bar' },
  {importantKey: 'x', foo: 'bar' },
  {importantKey: 'y', foo: 'bar' },
  { importantKey: 'z', foo: 'bar' },
]

document.write(JSON.stringify(data) + "<br>");

const map = {};
for (i in data)
{
  const key = data[i].importantKey;
  map[key] = (map[key] || 0) + 1;
  document.write(key); // zyzxyz
}
document.write("<br>map = " + JSON.stringify(map)); // {"z":3,"y":2,"x":1}

const k = [];
for(i in map) {
  //k.push(map[i]);
  k.splice(map[i] - 'x', 0, map[i]);
}
document.write("<br>k = " + JSON.stringify(k)); // [1,2,3]
      

Run codeHide result


0


source







All Articles