Reputation: 1669
I have the following object:
const object = {
user1: {
"article1": {}
},
user2: {
"article2": {},
"article3": {},
"article4": {}
},
user3: {
"article5": {}
},
user4: {
"article6": {}
}
};
I can count the user articles using method below.
const user1count = (object && object.user1 && Object.keys(object.user1).length) || 0
const user2count = (object && object.user2 && Object.keys(object.user2).length) || 0
const user3count = (object && object.user3 && Object.keys(object.user3).length) || 0
const user4count = (object && object.user4 && Object.keys(object.user4).length) || 0
Is there a more optimal method someone can suggest? I would prefer an object like one below.
const counts = {
user1: 1,
user2: 3,
user3: 1,
user4: 1
};
Thanks in advance.
Upvotes: 4
Views: 479
Reputation: 39322
You can make use of Object.entries()
, Object.keys()
and .reduce()
methods to get the desired output:
const object = {
user1: {
"article1": {}
},
user2: {
"article2": {},
"article3": {},
"article4": {}
},
user3: {
"article5": {}
},
user4: {
"article6": {}
}
};
const counts = Object.entries(object)
.reduce((r, [k, o]) => (r[k] = Object.keys(o).length, r), {});
console.log(counts);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 3
Reputation: 410
You can use forEach loop
const object = {
user1: {
"article1": {}
},
user2: {
"article2": {},
"article3": {},
"article4": {}
},
user3: {
"article5": {}
},
user4: {
"article6": {}
}
};
Object.keys(object).forEach(o => {
console.log(o, Object.keys(object[o]))
if (typeof object[o] == 'object') {
console.log(Object.keys(object[o]).length);
}
})
Upvotes: 3
Reputation: 50694
You can use Object.assign()
with Object.entries()
. First, you can .map()
the entires to objects (with the key being the user and value the number of keys in that user object) and then assign each individual object in the mapped array to a single object:
const object = {user1: { "article1": {} }, user2: { "article2": {}, "article3": {}, "article4": {} }, user3: { "article5": {} }, user4: { "article6": {} }};
const res = Object.assign(
{},
...Object.entries(object).map(([key, obj]) => ({[key]: Object.keys(obj).length}))
);
console.log(res);
Upvotes: 1
Reputation: 35222
You could map
the entries
of the object. Create an array of entries with the same key and the value set the length of keys. Use Object.fromEntries()
to convert the entries to an object
const object = {
user1: {
"article1": {}
},
user2: {
"article2": {},
"article3": {},
"article4": {}
},
user3: {
"article5": {}
},
user4: {
"article6": {}
}
};
const entries = Object.entries(object).map(([k, v]) => [k, Object.keys(v).length]),
output = Object.fromEntries(entries);
console.log(output)
Upvotes: 3
Reputation: 439
const counts = Object.entries(object)
.reduce((acc, entry) => ({
...acc,
[entry[0]]: Object.keys(entry[1] || {}).length
}));
Upvotes: 1
Reputation: 22885
You don't need to check like this object && object.user1
. Just loop on outer object keys and then find the length. Create final object using reduce.
const input = {
user1: {
"article1": {}
},
user2: {
"article2": {},
"article3": {},
"article4": {}
},
user3: {
"article5": {}
},
user4: {
"article6": {}
}
};
const output = Object.keys(input).reduce((prev, key) => {
prev[key] = Object.keys(input[key]).length;
return prev;
}, {});
console.log(output);
Upvotes: 3