skip to Main Content

I have the following array:

var a = [
  { "box":"1", "product":"Pen", "color":"White" },
  { "box":"1", "product":"Pencil", "color":"Blue" },
  { "box":"1", "product":"Marker", "color":"Red" },
  { "box":"2", "product":"Paper", "color":"White"},
  { "box":"2", "product":"GlossPaper", "color":"Yello"},
  { "box":"3", "product":"Eraser", "color":"Pink"}
];

I would like to reformat it to look like:


a = {
    "box": [
        {
            "number": "1", "contents": [
                {"product": "Pen", "color": "White"},
                {"product": "Pencil", "color": "Blue"},
                {"product": "Marker", "color": "Red"}
            ]
        },
        {
            "number": "2", "contents": [
                {"product": "Paper", "color": "White"},
                {"product": "GlossPaper", "color": "Yellow"}
            ]
        },
        {
            "number": "3", "contents": [
                {"product": "Eraser", "color": "Pink"}
            ]
        }
    ]
}

I was experimenting with reduce and tried:

a = a.reduce(function(x, e) {
  var estKey = (e['box']);
  (x[estKey] ? x[estKey] : (x[estKey] = null || [])).push(e);
  return x;
}, {});

but this doesn’t produce the desired format. As you can tell, I’m introducing new properties number and contents

3

Answers


  1. You’re looking for Object.groupBy

    let groups = Object.groupBy(yourArray, obj => obj.box)
    let result = Object.entries(groups)
        .map(([number, contents]) => ({number, contents}))
    
    Login or Signup to reply.
  2. Since Object.groupBy is only available in very recent browsers, you can do this:

    const a = [
      { "box":"1", "product":"Pen", "color":"White" },
      { "box":"1", "product":"Pencil", "color":"Blue" },
      { "box":"1", "product":"Marker", "color":"Red" },
      { "box":"2", "product":"Paper", "color":"White"},
      { "box":"2", "product":"GlossPaper", "color":"Yello"},
      { "box":"3", "product":"Eraser", "color":"Pink"}
    ];
    
    const b = {
      box: Object.values(
        a.reduce((a, {box: n, product, color}) => (
          (a[n] ??= {number: n, contents:[]}).contents.push({product, color}), a), 
          {}
        )
      )
    }
    
    console.log(b)
    Login or Signup to reply.
  3. const data = [
      { "box":"1", "product":"Pen", "color":"White" },
      { "box":"1", "product":"Pencil", "color":"Blue" },
      { "box":"1", "product":"Marker", "color":"Red" },
      { "box":"2", "product":"Paper", "color":"White"},
      { "box":"2", "product":"GlossPaper", "color":"Yello"},
      { "box":"3", "product":"Eraser", "color":"Pink"}
    ];
    
    const boxes = Object.groupBy(data, obj => obj.box);
    
    const finalResult = { 
      box: Object.keys(boxes)
        .map((key, index) => (
          {number: index+1, 
          contents: boxes[key]
                    .map(({ product, color}) => ({ product, color}))})
        )};
        
    console.log("finalResult", finalResult);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search