Looking for a very simple, elegant solution to count the frequency of different values in a javascript object. For example:
var input = [
{"a": "1", "b": "2"},
{"a": "2", "b": "2"},
{"a": "2", "b": "2", "c": "2"},
{"a": "bananas"}
]
var output = {
"a": {"1": 1, "2": 2, "bananas": 1},
"b": {"2": 3},
"c": {"2": 1},
}
I could probably loop over everything manually, but is there a simple and elegant solution, probably using reducers?
CodePudding user response:
you can do something like this
const occurencies = data => data.reduce((res, item) => {
Object.entries(item).forEach(([k, v]) => {
const existing = res[k] || {}
existing[v] = (existing[v] || 0) 1
res[k] = existing
})
return res
}, {})
var input = [
{"a": "1", "b": "2"},
{"a": "2", "b": "2"},
{"a": "2", "b": "2", "c": "2"},
{"a": "bananas"}
]
console.log(occurencies(input))
CodePudding user response:
a reduce
and a forEach
. Object.entries
to get the entries of each element of input array. Nullish coalescing operator(??
) to shorten the logic acc[k]=acc[k]||{}
var input = [
{"a": "1", "b": "2"},
{"a": "2", "b": "2"},
{"a": "2", "b": "2", "c": "2"},
{"a": "bananas"}
]
const output = input.reduce((acc,curr)=>{
const entries = Object.entries(curr)
entries.forEach(([k,v])=>{
acc[k]??={} //initializing key if not present
acc[k][v]??=0 //initializing count if not present for each value
acc[k][v] //incrementing
})
return acc
},{})
console.log(output)