Reputation: 1
How can I get count of objects in the table. I want all objects looks like the same. E.g. in element "b" I don't have any objects, but in output I want to get all used objects with count 0.
INPUT DATA
{
a: {
obj3: [{...}, {...}]
},
b: { },
c: {
obj1: [{...}, {...}, {...}]
obj2: [{...}, {...}]
}
}
OUTPUT DATA
{
a: {
obj1: 0,
obj2: 0,
obj3: 2
},
b: {
obj1: 0,
obj2: 0,
obj3: 0
},
c: {
obj1: 3
obj2: 2,
obj3: 0
}
}
Upvotes: 0
Views: 352
Reputation: 23372
To keep the code generic and a bit easier to manage and understand, I would loop over your data twice: first to discover all the unique keys you need to handle, and second to fill the structure with the right data.
To get the right keys, I look at the values of the input object (we can ignore the a
, b
and c
keys).
We're interested in all keys of the objects in this layer. We can create a flat list of them using flatMap(Object.keys)
.
Because this list might contain duplicate keys, I store them in a Set
. This ensures all keys appear only once. With the example data you provided, we now have a Set
of "obj1", "obj2", "obj3"
.
We can now transform any object to an object that has all keys. I capture this transformation in a Result
constructor function.
This function creates a list of all keys ([...allKeys]
), map
s over them, and checks our input object for the existence of the key (obj[k]?
). If the key exists, we use its length. If not, we default to 0
.
To transform your whole object, I defined a mapObj
helper. This takes an object, applies a function to each of its values, and returns those in a new object with the same keys.
const input = {
a: {
obj3: [{}, {}]
},
b: { },
c: {
obj1: [{}, {}, {}],
obj2: [{}, {}]
}
};
// Set(3) {"obj1", "obj2", "obj3"}
const allKeys = new Set(
Object
.values(input)
.flatMap(Object.keys)
);
const Result = obj => Object.fromEntries(
[...allKeys].map(
(k) => [ k, obj[k]?.length || 0 ]
)
);
console.log(
mapObj(Result, input)
)
// Utils
function mapObj(f, o) {
return Object.fromEntries(
Object.entries(o).map(
([k, v]) => [k, f(v)]
)
)
}
Upvotes: 1
Reputation: 3844
This is my solution:
let input = {
a: {
obj3: [{x:1}, {x:2}]
},
b: {},
c: {
obj1: [{x:3}, {x:5}, {x:6}],
obj2: [{x:7}, {x:8}]
}
}
let output={};
Object.keys(input).forEach(key=>{
let item={obj1:0,obj2:0,obj3:0};
["obj1","obj2","obj3"].forEach(itemType=>{
if (input[key][itemType]){
item[itemType]= input[key][itemType].length;
}
})
output[key]=item;
});
console.log(output);
Upvotes: 0
Reputation: 2761
You can do something like this only if you want specific number of objX
as output and the key name is in the same format.
let input = {
a: {
obj3: [{x:1}, {x:2}]
},
b: { },
c: {
obj1: [{x:1}, {x:2}, {x:3}],
obj2: [{x:1}, {x:2}]
}
}
let output = {};
for (const [key, value] of Object.entries(input)) {
let result = {}
for (let i = 1; i < 4; i++) {
result['obj'+i] = value['obj'+i] ? value['obj'+i].length : 0;
}
output[key] = result;
}
console.log(output);
Upvotes: 1