1

I am trying to group objects from one array based on a value from another array, however I can't seem to find the right way to do it.

I have an array with orders which has a key-value pair like id: 999324 Now I have another array for products that has many objects which has different id's or matching id's like orderlineId: 999324. Now those objects with a matching ID should be grouped together.

Order array

[{
    "agreement": null,
    "channel": null,
    "collection": "Colect 2019",
    "comment": "Comment here",
    "customerNo": "140159",
    "customerOrderReference": "CustomerOReference",
    "customerPriceGroup": "1,7",
    "erpOrderReference": "1337ORDERREFERENCE",
    "externalUrl": null,
    "id": 99945333,
},
{
    "agreement": null,
    "channel": null,
    "collection": "Colect 2019",
    "comment": "Comment here",
    "customerNo": "140159",
    "customerOrderReference": "CustomerOReference",
    "customerPriceGroup": "1,7",
    "erpOrderReference": "1337ORDERREFERENCE",
    "externalUrl": null,
    "id": 99945334,
]

Products array

[{
        "crossReference": null,
        "currency": "EU",
        "deliverySubBlock": null,
        "eanCode": "8717945155406",
        "grossLineAmount": 99.99,
        "grossWholesalePrice": 99.99,
        "id": 1156718740,
        "orderlineId": 99945334,
},
{
        "crossReference": null,
        "currency": "EU",
        "deliverySubBlock": null,
        "eanCode": "8717945155406",
        "grossLineAmount": 99.99,
        "grossWholesalePrice": 99.99,
        "id": 1156718740,
        "orderlineId": 99945334,
},
{
        "crossReference": null,
        "currency": "EU",
        "deliverySubBlock": null,
        "eanCode": "8717945155406",
        "grossLineAmount": 99.99,
        "grossWholesalePrice": 99.99,
        "id": 1156718740,
        "orderlineId": 99945334
}]

Preferred orders array would be an array with a nested array with all the objects from the products array that matches the orders.id id with products.orderlineId

[{
{
    "agreement": null,
    "channel": null,
    "collection": "Colect 2019",
    "comment": "Comment here",
    "customerNo": "140159",
    "customerOrderReference": "CustomerOReference",
    "customerPriceGroup": "1,7",
    "erpOrderReference": "1337ORDERREFERENCE",
    "externalUrl": null,
    "id": 99945334,
    "orderLines" [
     {
        "crossReference": null,
        "currency": "EU",
        "deliverySubBlock": null,
        "eanCode": "8717945155406",
        "grossLineAmount": 99.99,
        "grossWholesalePrice": 99.99,
        "id": 1156748740,
        "orderlineId": 99945334
     },
     {
        "crossReference": null,
        "currency": "EU",
        "deliverySubBlock": null,
        "eanCode": "8717945155407",
        "grossLineAmount": 9.99,
        "grossWholesalePrice": 199.99,
        "id": 1156718720,
        "orderlineId": 99945334
      }
},
{
    "agreement": null,
    "channel": null,
    "collection": "Colect 2019",
    "comment": "Comment here",
    "customerNo": "140159",
    "customerOrderReference": "CustomerOReference",
    "customerPriceGroup": "1,7",
    "erpOrderReference": "1337ORDERREFERENCE",
    "externalUrl": null,
    "id": 99945350,
    "orderLines" [
     {
        "crossReference": null,
        "currency": "EU",
        "deliverySubBlock": null,
        "eanCode": "8717945155406",
        "grossLineAmount": 99.99,
        "grossWholesalePrice": 99.99,
        "id": 1156748740,
        "orderlineId": 99945350
     },
     {
        "crossReference": null,
        "currency": "EU",
        "deliverySubBlock": null,
        "eanCode": "8717945155407",
        "grossLineAmount": 3.99,
        "grossWholesalePrice": 299.99,
        "id": 1156718720,
        "orderlineId": 99945350
      }
}

I tried many ways like this


for(let i=0; i<orders.length; i++) {
  merged.push({
   ...products[i], 
   ...(orders.find((itmInner) => itmInner.id === products[i].orderlineId))}
  );
}

But that doesn't seem to work correctly.

I hope I made it clear what I try to achieve as it's my first question on Stackoverflow.

2
  • 1
    Some simplified sample data and expected results would be helpful as per minimal reproducible example Commented Jun 15, 2020 at 0:36
  • Thanks Charlie, I've included the expected results, I hope it's more understandable now. Commented Jun 15, 2020 at 0:50

2 Answers 2

1

Uses filter to filter for matching id. Mutates orders array objects.
For large data sets, you will want to use an object map lookup table to track ids so you don't have to iterate the entire products array for every order (O(N) vs O(N^2))
(You would create an object map on orders ids, so you iterate orders array only once and then products array only once)

orders.forEach(order=>
  order.productLines = products.filter(p => p.orderlineId === order.id)
)

console.log(orders)
<script>
orders = [{
    "agreement": null,
    "channel": null,
    "collection": "Colect 2019",
    "comment": "Comment here",
    "customerNo": "140159",
    "customerOrderReference": "CustomerOReference",
    "customerPriceGroup": "1,7",
    "erpOrderReference": "1337ORDERREFERENCE",
    "externalUrl": null,
    "id": 99945333,
},
{
    "agreement": null,
    "channel": null,
    "collection": "Colect 2019",
    "comment": "Comment here",
    "customerNo": "140159",
    "customerOrderReference": "CustomerOReference",
    "customerPriceGroup": "1,7",
    "erpOrderReference": "1337ORDERREFERENCE",
    "externalUrl": null,
    "id": 99945334,
}]

products = [{
        "crossReference": null,
        "currency": "EU",
        "deliverySubBlock": null,
        "eanCode": "8717945155406",
        "grossLineAmount": 99.99,
        "grossWholesalePrice": 99.99,
        "id": 1156718740,
        "orderlineId": 99945334,
},
{
        "crossReference": null,
        "currency": "EU",
        "deliverySubBlock": null,
        "eanCode": "8717945155406",
        "grossLineAmount": 99.99,
        "grossWholesalePrice": 99.99,
        "id": 1156718740,
        "orderlineId": 99945334,
},
{
        "crossReference": null,
        "currency": "EU",
        "deliverySubBlock": null,
        "eanCode": "8717945155406",
        "grossLineAmount": 99.99,
        "grossWholesalePrice": 99.99,
        "id": 1156718740,
        "orderlineId": 99945334
}]
</script>

Sign up to request clarification or add additional context in comments.

Comments

0

What you would want to do is first include the order in the merged array as the order will always be one of the products and then include the orderlineId of the product which matches the id of the order.

Also, as you have said orders array will have all the orders and products array may have more elements than orders so the for loop should run till the length of products array. Because you want the merged array to contain all the elements with same value to be grouped and otherwise not.

I think this is what you want to achieve?

products.forEach(product => {
    let order = orders.find(order => product.orderlineId === order.id)
    merged = [...merged, { ...product, ...order } ]
})

say we have orders array

let orders = [{ id: 23432}, {id: 11111}, {id: 56789}];
let products = [{orderlineId: 83}, {orderlineId: 11111}, {orderlineId: 56789}, {orderlineId: 23432}]
let merged = []

// running the above map would give ...

merged = [
{orderlineId: 83}, 
{orderlineId: 11111, id: 11111 ,
{orderlineId: 56789, id: 56789},
{orderlineId: 23432, id: 23432}
]

Was that what you wanted? Then replace products with orders in your loop and orders with products array.

4 Comments

Thanks Baraja, really appreciate your input, it definitely works!
Your welcome. You can upvote if you like my answer.
I actually did Baraja :), but since I am a new member it wont show up in the frontend yet. I need more points for that apparently. It is counted though.
Thank you so much Coen. I am also new to StackOverflow and thought to join here to find more opportunities.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.