0

I have seen similar question in stackoverflow, by using reduce method like this post: Javascript - Group by one property of object in an array of objects.

but I would like to get back a result as array [], instead of an object {}.

Here is a example

Input:

[
  {
    "name": "ABC Equity",
    "category": "Equity"
  },
  {
    "name": "EBC Bonds",
    "category": "Bond"
  },
  {
    "name": "Corporate Bonds",
    "category": "Bond"
  },
  {
    "name": "Private Equity",
    "category": "Equity"
  },
  {
    "name": "Fixed abc",
    "category": "Fixed"
  }
]

Expected after regrouping:

[
  {
    label: 'Equity',
    options: [
      { value: 'ABC Equity', label: 'ABC Equity'},
      { value: 'Private Equity', label: 'Private Equity'},
    ],
  },
  {
    label: 'Bond',
    options: [
      { value: 'EBC Bonds', label: 'EBC Bonds'},
      { value: 'Corporate Bonds', label: 'Corporate Bonds' },
    ],
  },
   {
    label: 'Fixed',
    options: [
      { value: 'Fixed abc', label: 'Fixed abc'}
    ],
  },
]
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • group into object like `{Equity: {label:Equity,options:[...]},....}` and then use `Object.values` on the object – cmgchess Apr 20 '23 at 07:14
  • Please visit [help], take [tour] to see what and [ask]. Do some research, search for related topics on SO; if you get stuck, post a [mcve] of your attempt, noting input and expected output, preferably in a [Stacksnippet](https://blog.stackoverflow.com/2014/09/introducing-runnable-javascript-css-and-html-code-snippets/) – mplungjan Apr 20 '23 at 07:30

2 Answers2

3

To convert the object created using a reduce, you need to take the values of the object after reducing.

Note the use of nullish coalescing assignment operators ??=

This code is O(n) (runs once over the input)

const arr1 = [ 
  { "name": "ABC Equity",      "category": "Equity" },
  { "name": "EBC Bonds",       "category": "Bond"   },
  { "name": "Corporate Bonds", "category": "Bond"   },
  { "name": "Private Equity",  "category": "Equity" },
  { "name": "Fixed abc",       "category": "Fixed"  }
];

const arr2 = Object.values(
  arr1.reduce((acc,{name,category}) => {
    acc[category] ??= {};
    acc[category].label = category;
    acc[category].options ??= [];
    acc[category].options.push({"value": name, "label": name});
    return acc;
  },{})
);

console.log(arr2);
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • Thanks for your effort, when u said, JSON is a string format in obj, string format in obj means like this "{'key1' : 'value'}" ? – user21357723 Apr 20 '23 at 08:20
  • coz i still dont quite understand the not relevant part? – user21357723 Apr 20 '23 at 08:22
  • No. JSON is a string representation of JavaScript objects. It is what you get when you do `JSON.stringify(obj)` where obj can be an object `{}` or array (which is also an object) `[]` – mplungjan Apr 20 '23 at 08:22
  • Please have a look at [javascript-object-vs-json](https://stackoverflow.com/questions/8294088/javascript-object-vs-json) – mplungjan Apr 20 '23 at 08:23
  • Also study https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON - there is no such thing as ***a JSON***. It is an object or a JSON string – mplungjan Apr 20 '23 at 08:24
  • 1
    so , my statement in the topic should be... I dont want a result in a object in {} format , but array format... In the post I mentioned, the result is in a object in {} format – user21357723 Apr 20 '23 at 08:39
  • is that what u were syaing? – user21357723 Apr 20 '23 at 08:39
  • Indeed, that is what I meant – mplungjan Apr 20 '23 at 11:13
0

This should work:

const input = [
  {
    "name": "ABC Equity",
    "category": "Equity"
  },
  {
    "name": "EBC Bonds",
    "category": "Bond"
  },
  {
    "name": "Corporate Bonds",
    "category": "Bond"
  },
  {
    "name": "Private Equity",
    "category": "Equity"
  },
  {
    "name": "Fixed abc",
    "category": "Fixed"
  }
]

let grouped = input.reduce((arr, cur) => {
  let group = arr.find(i => i.label == cur.category)
  if (group) {
    group.options.push(cur)
  } else {
    arr.push({ label: cur.category, options: [cur] })
  }
  return arr
}, [])

console.log(grouped)
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Shalom Peles
  • 2,285
  • 8
  • 21