Connor
Connor

Reputation: 349

Loop through each object in a array of arrays find the id, match it to another object in an array and concatenate them together

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>

Upvotes: 2

Views: 1829

Answers (2)

user120242
user120242

Reputation: 15268

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>

Upvotes: 1

Rory McCrossan
Rory McCrossan

Reputation: 337733

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.

Upvotes: 1

Related Questions