makugym
makugym

Reputation: 1

How to count the number of objects in the table

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

Answers (3)

user3297291
user3297291

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.

Getting the right keys

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".

Transforming an object

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]), maps 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.

Transforming the whole input

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

The KNVB
The KNVB

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

Rifat Bin Reza
Rifat Bin Reza

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

Related Questions