1

I have an issue and the way to solve it is by grouping the elements in my array based on their properties (the ID). Let me explain :

This is the given array :

[ { project_id: 'project:710f57c6bb18753dfeaad60b7a7437df',
    end_date: '2017-05-18',
    invoice_method: 'FixedFee',
    amount: '1.000000',
    price: '134.000000' },
  { project_id: 'project:710f57c6bb18753dfeaad60b7a7437df',
    start_date: '2017-06-01',
    subscription_cycle: 'Month',
    invoice_method: 'Subscription',
    amount: '1.000000',
    price: '49.000000' },

{ project_id: 'project:abcdefghijklmnop',
    start_date: '2017-06-01',
    subscription_cycle: 'Month',
    invoice_method: 'Subscription',
    amount: '1.000000',
    price: '49.000000'},

{ project_id: 'project:abcdefghijklmnop',
    start_date: '2017-06-01',
    subscription_cycle: 'Month',
    invoice_method: 'Subscription',
    amount: '1.000000',
    price: '49.000000'},

]

The first 2 elements in this big array have the same ID and the last 2 have the same ID, so the output I would like is something like :

//MAIN ARRAY
[ 
    //ONE CHUNK
    [
        { project_id: 'project:710f57c6bb18753dfeaad60b7a7437df',
        end_date: '2017-05-18',
        invoice_method: 'FixedFee',
        amount: '1.000000',
        price: '134.000000' },

        { project_id: 'project:710f57c6bb18753dfeaad60b7a7437df',
        start_date: '2017-06-01',
        subscription_cycle: 'Month',
        invoice_method: 'Subscription',
        amount: '1.000000',
        price: '49.000000' }
    ]

    //ONE CHUNK
    [
        { project_id: 'project:abcdefghijklmnop',
        start_date: '2017-06-01',
        subscription_cycle: 'Month',
        invoice_method: 'Subscription',
        amount: '1.000000',
        price: '49.000000'},

        { project_id: 'project:abcdefghijklmnop',
        start_date: '2017-06-01',
        subscription_cycle: 'Month',
        invoice_method: 'Subscription',
        amount: '1.000000',
        price: '49.000000'}

    ]


]
E_net4
  • 27,810
  • 13
  • 101
  • 139
Kevin.a
  • 4,094
  • 8
  • 46
  • 82
  • 1
    Not an exact duplicate, but potentially helpful: [How to group an array of objects by key](https://stackoverflow.com/a/40774906/1650337) – DBS Jul 03 '20 at 15:35
  • 1
    Try checking this answer: https://stackoverflow.com/a/34890276/2223729 – Amadare42 Jul 03 '20 at 15:36

3 Answers3

3

Some like this for grouping based on key name.

Not exact but you can do like this. .reduce() will work.

Here keyName project_id is used to group array of objects.

const data = [ { project_id: 'project:710f57c6bb18753dfeaad60b7a7437df',
    end_date: '2017-05-18',
    invoice_method: 'FixedFee',
    amount: '1.000000',
    price: '134.000000' },
  { project_id: 'project:710f57c6bb18753dfeaad60b7a7437df',
    start_date: '2017-06-01',
    subscription_cycle: 'Month',
    invoice_method: 'Subscription',
    amount: '1.000000',
    price: '49.000000' },

{ project_id: 'project:abcdefghijklmnop',
    start_date: '2017-06-01',
    subscription_cycle: 'Month',
    invoice_method: 'Subscription',
    amount: '1.000000',
    price: '49.000000'},

{ project_id: 'project:abcdefghijklmnop',
    start_date: '2017-06-01',
    subscription_cycle: 'Month',
    invoice_method: 'Subscription',
    amount: '1.000000',
    price: '49.000000'
  }]

let result = data.reduce(function (r, a) {
        r[a.project_id] = r[a.project_id] || [];
        r[a.project_id].push(a);
        return r;
    }, []);

console.log(result);
xMayank
  • 1,875
  • 2
  • 5
  • 19
1

As you are not asking for the code, here is an outline:

  1. Create a Map or object so that you can quickly find an id (as key) and the associated subarray (as value).

  2. Iterate your data, and for each object look up the subarray in your Map/object. If there is no entry for that id yet, then create it for that id as an empty subarray. In either case push the current object to that subarray

  3. Finally get all those subarrays from your Map/object and concatenate them to one final array.

Hidden code, in case you cannot make it work:

const data = [ { project_id:'project:710f57c6bb18753dfeaad60b7a7437df', end_date: '2017-05-18',invoice_method: 'FixedFee',amount: '1.000000',price: '134.000000' },{ project_id: 'project:710f57c6bb18753dfeaad60b7a7437df',start_date: '2017-06-01',subscription_cycle: 'Month',invoice_method: 'Subscription',amount: '1.000000',price: '49.000000' },{ project_id: 'project:abcdefghijklmnop',start_date: '2017-06-01',subscription_cycle: 'Month',invoice_method: 'Subscription',amount: '1.000000',price: '49.000000'},{ project_id: 'project:abcdefghijklmnop',start_date: '2017-06-01',subscription_cycle: 'Month',invoice_method: 'Subscription',amount: '1.000000',price: '49.000000'}];

let map = new Map(data.map(o => [o.project_id, []]));
data.forEach(o => map.get(o.project_id).push(o));
let result = Array.from(map.values());

console.log(result);
trincot
  • 317,000
  • 35
  • 244
  • 286
  • @trincot. Just for curiosity, what you think of my solution instead? – Raffobaffo Jul 03 '20 at 15:45
  • @Raffobaffo, you just deleted it, but that looks like it uses this approach (using`acc` as the object to map id to subarray) – trincot Jul 03 '20 at 15:48
  • OK, I see people are posting code despite you saying you were not looking for code. If you want the code to go with this outline, let me know, and I'll add it. – trincot Jul 03 '20 at 15:50
  • @trincot yes, I deleted because the other posted solution is better. It uses a short-circuit evaluation while I was using an if nested in the reducer. – Raffobaffo Jul 03 '20 at 15:53
  • @Raffobaffo, that is a detail of the code. The OP was not asking for code anyway, but people don't read... – trincot Jul 03 '20 at 15:54
  • 1
    @trincot Yes right. Let's say I'm shy :P. It's just I started to "give back" answering questions here just 3 days ago, and I already been pretty stressed with other users downvoting or writing sense-less comments. So I seen an answer (in my opinion) a tick better was already posted, and I thought was better to remove mine. Long explanation – Raffobaffo Jul 03 '20 at 15:57
1

Check this solution, May this help you.

var initailArray = [ { project_id: 'project:710f57c6bb18753dfeaad60b7a7437df',
    end_date: '2017-05-18',
    invoice_method: 'FixedFee',
    amount: '1.000000',
    price: '134.000000' },
  { project_id: 'project:710f57c6bb18753dfeaad60b7a7437df',
    start_date: '2017-06-01',
    subscription_cycle: 'Month',
    invoice_method: 'Subscription',
    amount: '1.000000',
    price: '49.000000' },

{ project_id: 'project:abcdefghijklmnop',
    start_date: '2017-06-01',
    subscription_cycle: 'Month',
    invoice_method: 'Subscription',
    amount: '1.000000',
    price: '49.000000'},

{ project_id: 'project:abcdefghijklmnop',
    start_date: '2017-06-01',
    subscription_cycle: 'Month',
    invoice_method: 'Subscription',
    amount: '1.000000',
    price: '49.000000'},
];

let dummyObj = {};

initailArray.forEach((data)=>{
  if(!dummyObj[data.project_id]){
    dummyObj[data.project_id] = [data];
  }else{
    dummyObj[data.project_id].push(data);
  }
});

let finalResult = [Object.values(dummyObj)];

console.log("finalResult", finalResult);
SHUBHAM JAIN
  • 44
  • 1
  • 5