1

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
  }
]
2

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.