Samir Quluzadeh
Samir Quluzadeh

Reputation: 9

Same objects merged one array

I have input like this. I tried some solutions. But it doesn't work. I need to merge same invoice_nr objects to one array. Also I need other objects another array. All arrays must be another array.

const result = [
  {
    invoice_nr: 16,
    order_id: 5577,
    color: 'red'
  },
  {
    invoice_nr: 16,
    order_id: 5577,
    color: 'yellow'
  },
  {
    invoice_nr: 17,
    order_id: 5574,
    color: 'green'
  },
  {
    invoice_nr: 18,
    order_id: 5578,
    color: 'yellow'
  },
  {
    invoice_nr: 18,
    order_id: 5578,
    color: 'blue'
  }
];

But, I need output like this. How can I achieve that in javascript? Array must be like this.

const result = [
  [
  {
    invoice_nr: 16,
    order_id: 5577,
    color: 'red'
  },
  {
    invoice_nr: 16,
    order_id: 5577,
    color: 'yellow'
  }
  ],
  [
  {
    invoice_nr: 17,
    order_id: 5574,
    color: 'green'
  }
  ],
  [
  {
    invoice_nr: 18,
    order_id: 5578,
    color: 'yellow'
  },
  {
    invoice_nr: 18,
    order_id: 5578,
    color: 'blue'
  }
  ]
];

Upvotes: 0

Views: 77

Answers (3)

gureenkov56
gureenkov56

Reputation: 172

You have to at a first get array of unique ID and use it for filter you data.

const result = [
  {
    invoice_nr: 16,
    order_id: 5577,
    color: 'red'
  },
  {
    invoice_nr: 16,
    order_id: 5577,
    color: 'yellow'
  },
  {
    invoice_nr: 17,
    order_id: 5574,
    color: 'green'
  },
  {
    invoice_nr: 18,
    order_id: 5578,
    color: 'yellow'
  },
  {
    invoice_nr: 18,
    order_id: 5578,
    color: 'blue'
  }
];

let uniq = [];
let res = [];
// get unique ID
result.forEach(i => !uniq.includes(i.invoice_nr) ? uniq.push(i.invoice_nr) : '' );
// filter by ID
uniq.forEach(id => {
    res.push(result.filter(o => o.invoice_nr === id))
})
// that you need in res
console.log(res);

Upvotes: 0

Trevor Dixon
Trevor Dixon

Reputation: 24362

If they're in order, then I'd reduce like this:

result.reduce((arr, item) => {
    const group = arr.at(-1), prevItem = group?.at(-1);
    if (prevItem?.invoice_nr === item.invoice_nr) {
        group.push(item);
    } else {
        arr.push([item]);
    }
    return arr;
}, []);

Upvotes: 0

Asraf
Asraf

Reputation: 1369

You can use .reduce() to build a lookup object where key is the invoice_nr and value is an array. In every iteration look for a key is already exists in lookup object if it is then push to the existing list, if it's not add a new property in the lookup object.

const result = [ { invoice_nr: 16, order_id: 5577, color: 'red' }, { invoice_nr: 16, order_id: 5577, color: 'yellow' }, { invoice_nr: 17, order_id: 5574, color: 'green' }, { invoice_nr: 18, order_id: 5578, color: 'yellow' }, { invoice_nr: 18, order_id: 5578, color: 'blue' } ];

const res = result.reduce((a,b) => ((a[b.invoice_nr] ??= []).push(b),a),{});
console.log(Object.values(res));
.as-console-wrapper { max-height: 100% !important }

Upvotes: 4

Related Questions