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.
source to share
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);
source to share
Using the Array function map
and then filter
.
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));
source to share
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);
source to share
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]
source to share