How to simplify function which returns an object?

Tags: ,



I have a function which returns an object but I don’t like that I gotta declare it first and then do forEach method

export default (data) => {
  const keysWithDotsObject = {};
  Object.keys(data).forEach((keyWithDot) => {
    Object.keys(data[keyWithDot]).forEach((key) => {
      keysWithDotsObject[`${keyWithDot}.${key}`] = data[keyWithDot][key];
    });
  });
  return keysWithDotsObject;
};

I think there should be something like this

export default (data) => {
  const keysWithDotsObject = Object.keys(data).map((keyWithDot) => {
    Object.keys(data[keyWithDot]).map((key) => ({
      [`${keyWithDot}.${key}`]: data[keyWithDot][key],
    }));
  });
  return keysWithDotsObject;
};

But for some reason, it doesn’t work.

PS: In this part —

[`${keyWithDot}.${key}`]

— I’m trying to create a key with a name separated by a dot (I don’t like that, but that’s what back-end wants me to)

Input :

Query1 = {
  locus_ids: [25, 26],
  microorganism_ids: [12],
};

Output :

Query1.locus_ids: [25, 26],
Query1.microorganism_ids: [12]

I also would like any suggestions on how to write more readable code

Answer

Did you consider using reduce?

export default (data) => Object.keys(data).reduce((acc, keyWithDot) => (
  Object.keys(data[keyWithDot]).forEach((key) => {
    acc[`${keyWithDot}.${key}`] = data[keyWithDot][key];
  }), 
  acc
), {});

You can also use Object.fromEntries, map and flatMap should do the job:

export default (data) => 
  Object.fromEntries(
    Object.keys(data).flatMap((keyWithDot) => 
      Object.keys(data[keyWithDot]).map((key) => [`${keyWithDot}.${key}`, data[keyWithDot][key]])
    )
  );

First, you build an array for each subentry, for each subentry, you flatten the array you got into an array of key/value, then with Object.fromEntries, you make a new object!



Source: stackoverflow