2
\$\begingroup\$

I have the following data

const data = [
  {
    _id: "John Doe",
    cashShare: 2,
    stockShare: 3000,
  },
  {
    _id: "Jane Doe",
    cashShare: 0,
    stockShare: 20,
  },
  {
    _id: "Jack Doe",
    cashShare: 311,
    stockShare: 1311,
  },
];

I want to transform it into:

[
  { _id: 'John Doe', label: 'Cash Share', value: 2 },
  { _id: 'Jane Doe', label: 'Cash Share', value: 0 },
  { _id: 'Jack Doe', label: 'Cash Share', value: 311 },
  { _id: 'John Doe', label: 'Stock Share', value: 3000 },
  { _id: 'Jane Doe', label: 'Stock Share', value: 20 },
  { _id: 'Jack Doe', label: 'Stock Share', value: 1311 }
]

So I did this:

const cashShare = data.map(({ _id, cashShare, stockShare }) => {
  return {
    _id,
    label: "Cash Share",
    value: cashShare,
  };
});

const stockShare = data.map(({ _id, cashShare, stockShare }) => {
  return {
    _id,
    label: "Stock Share",
    value: stockShare,
  };
});

const mergedData = [...cashShare, ...stockShare];
console.log(mergedData);

I was wondering if there was a better way of doing this because I feel like this is unnecessary long, but it is clear what I am doing.

\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

You could map each object to a list of objects (one for each label), and then use Array.flat() to turn the nested array into a flat array. If you care about ordering, you could then sort by label to put all the Cash Shares first.

const data = [
  {
    _id: "John Doe",
    cashShare: 2,
    stockShare: 3000,
  },
  {
    _id: "Jane Doe",
    cashShare: 0,
    stockShare: 20,
  },
  {
    _id: "Jack Doe",
    cashShare: 311,
    stockShare: 1311,
  },
];

const mergedData = data.map(({ _id, cashShare, stockShare }) => [
  {
    _id,
    label: "Cash Share",
    value: cashShare,
  },
  {
    _id,
    label: "Stock Share",
    value: stockShare,
  }
]).flat()
.sort((lhs, rhs) => lhs.label < rhs.label ? -1 : 1); // sort is only necessary if you care about order
console.log(mergedData);

I'm not sure how the performance of this option compares to yours. I've assumed you're mostly thinking about readability rather than efficiently processing large datasets.

\$\endgroup\$
2
\$\begingroup\$

A short review;

  • You process the list twice, ideally you process the list only once

    • You can run 1 function once per object with map and then flat
    • You could even run flatMap which is faster than running map and flat separately
  • The code for cashShare and stockShare is violating DRY I would use a function called `getLabelValue that looks like this

      function getLabelValue(o, label){
        return {
          _id: o._id,
          label,
          value: o[label]
        }
      }
    
\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.