2

So I have an array called 'products' which contains objects and each object has a unique id. I also have another array called 'productsAdditionalInfo' which contains additional info relating to 'products' and each object has a owner_id which matches to one of the objects in the 'products' array. The 'productsAdditionalInfo' may have many objects inside an array but will always have the same owner_id relative to that array.

I'm, trying to loop through the 'productsAdditionalInfo' array get the 'owner_id' and match it to the 'id' in the products array then add the namespace as a key and the value as the value and then return it as a new array. However, it appears I'm stuck on the first hurdle. I get the first key of "Duration" in the console then I get 'namespace' of undefined.

I hope this makes sense if not I've commented out an example of how it's supposed to be. I appreciate any help.

Edit: Some people have suggested that this is similar/the same as another question where you merge them together but I believe my question is different since I'm not completely merging them together just certain bits of info.

let products = [ {id: 102, type: "toy"}, {id: 245, type: "food"}, {id: 312, type: "clothes"} ]

let productsAdditionalInfo = [ 
  [{namespace: "Duration", value: 5, owner_id: 245}, {namespace: "effect", value: "Tail", owner_id: 245}], 
  [{namespace: "Supplier", owner_id: 312, value: "rev"}], 
  [{namespace: "amount", value: 0, owner_id: 102}, {namespace: "effect", value: "plush", owner_id: 102}] 
]

$.each(productsAdditionalInfo, function( index, product ) {
  console.log( product[index].namespace );
});


// let whatItShouldBe = [ {id: 102, type: "toy", amount: 0, effect: "plush" }, {id: 245, type: "food", Duration: 5, effect: "Tail"}, {id: 312,  type: "clothes", Supplier: "rev"} ]
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

3
  • 3
    product[index] inside the each loop is wrong - product is one of the elements of productsAdditionalInfo at this point already; and index is its index inside of that. Each product itself is an array of objects again though, so you probably need a second, nested loop at this point. Commented Apr 27, 2020 at 13:58
  • Does this answer your question? How to merge multiple array of object by ID in javascript? Commented Apr 27, 2020 at 14:02
  • 1
    Unfortunately not as I'm not completely merging them I just want the "namespace" and 'value' to be merged Commented Apr 27, 2020 at 14:05

2 Answers 2

1

One way to achieve this would be to loop through each product, retrieving the associated productAdditionsInfo based on the owner_id. From there you can create an object from the additions and merge the two together, something like this:

let products = [{id: 102, type: "toy"}, {id: 245, type: "food"}, {id: 312, type: "clothes"}]
let productsAdditionalInfo = [ 
  [{namespace: "Duration", value: 5, owner_id: 245}, {namespace: "effect", value: "Tail", owner_id: 245}], 
  [{namespace: "Supplier", owner_id: 312, value: "rev"}], 
  [{namespace: "amount", value: 0, owner_id: 102}, {namespace: "effect", value: "plush", owner_id: 102}] 
]

let merged = products.map(p => {
  var info = productsAdditionalInfo.filter(i => i[0].owner_id == p.id)[0].map(i => ({ [i.namespace]: i.value }));
  info.push(p);
  return Object.assign(...info);
});

console.log(merged);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

This is assuming that the second-level arrays within productsAdditionalInfo are always grouped by the same owner_id.

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

2 Comments

Thank you very much! It should even work in IE which is a nice bonus but not essential.
You can use .apply $.extend $.map and $.grep if you want IE support using jQuery.
1

let products = [ {id: 102, type: "toy"}, {id: 245, type: "food"}, {id: 312, type: "clothes"} ]

let productsAdditionalInfo = [ 
  [{namespace: "Duration", value: 5, owner_id: 245}, {namespace: "effect", value: "Tail", owner_id: 245}], 
  [{namespace: "Supplier", owner_id: 312, value: "rev"}], 
  [{namespace: "amount", value: 0, owner_id: 102}, {namespace: "effect", value: "plush", owner_id: 102}] 
]

const flatPAI = productsAdditionalInfo.flat();

console.log(
products.map( p => 
  Object.assign(p,
    ...flatPAI.filter(
         info => info.owner_id == p.id
       ).map(
         info => ({[info.namespace]: info.value})))
)
);



// let whatItShouldBe = [ {id: 102, type: "toy", amount: 0, effect: "plush" }, {id: 245, type: "food", Duration: 5, effect: "Tail"}, {id: 312,  type: "clothes", Supplier: "rev"} ]
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Comments

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.