Home > Software design >  How to flatten JavaScript objects
How to flatten JavaScript objects

Time:10-26

I need to transform from one schema to another. Is there any way of achieving this without doing a for loop?

Original data

[
  {
    "browser": "Chrome",
    "count": 73,
    "verdict": "detected"
  },
  {
    "browser": "Opera",
    "count": 3,
    "verdict": "detected"
  },
  {
    "browser": "Chrome",
    "count": 3,
    "verdict": "blocked"
  },
  {
    "browser": "Edge",
    "count": 1,
    "verdict": "detected"
  }
]

Transformed data

[
  {
    "browser": "Chrome",
    "detected":73,
    "blocked":3
  },
  {
    "browser": "Opera",
    "detected": 3,
    "blocked": 0
  },
  {
    "browser": "Edge",
    "detected": 1,
    "blocked": 0
  }
]

CodePudding user response:

Group them by the browser as a unique key, then the result is as easy as getting the values in the object.

const data=[{"browser":"Chrome","count":73,"verdict":"detected"},{"browser":"Opera","count":3,"verdict":"detected"},{"browser":"Chrome","count":3,"verdict":"blocked"},{"browser":"Edge","count":1,"verdict":"detected"}];

const grouped = data.reduce((o, { browser, count, verdict }) => {
    // If it's not in the map yet, add it as an empty entry
    if (!(browser in o)) o[browser] = { browser, detected: 0, blocked: 0 };
    
    // By now, it must be in the map, so it's as easy as adding the count to the verdict
    o[browser][verdict]  = count;

    // Return modified map for the next iteration
    return o;
}, {});

const result = Object.values(grouped); // Get the values of the map

console.log(result); // Done!
.as-console-wrapper { max-height: 100% !important; top: 0; }

See destructuring if you're wondering about what (o, { browser, count, verdict }) => is doing, and the in operator for checking if a key exists in an object.

CodePudding user response:

I'd create a temporary map, so it can be accessed by its keys.
Then you can iterate the elements and update the temp map:

const initial = [{
    "browser": "Chrome",
    "count": 73,
    "verdict": "detected"
  },
  {
    "browser": "Opera",
    "count": 3,
    "verdict": "detected"
  },
  {
    "browser": "Chrome",
    "count": 3,
    "verdict": "blocked"
  },
  {
    "browser": "Edge",
    "count": 1,
    "verdict": "detected"
  }
];

const defaultValues = {
  detected: 0,
  blocked: 0
};
const ans = initial.reduce((acc, element) => {
  const {
    browser,
    verdict,
    count
  } = element;
  acc[browser] = {
    browser,
    ...(acc[browser] || defaultValues),
    [verdict]: count,
  };
  return acc;
}, {});

console.log(Object.values(ans));

  • Related