0

i have an Array called Factories and to that i would like to add the products available in each factory and then combine the two arrays so i get one nicely sorted array out. I have the biggest part done, however i can't seem to get the array added to each individual factory

factory array (simplyfied):

var F = [{ID: 2775030, name: "germany", products[0]},{ID: 2775031, name: "netherlands", product[1]}]

products array (simplied)

var products = [{ID: 2775030, product: 458, ProductName: "blue"}, {ID: 2775030, product: 324, ProductName: "green"}, {ID: 2775031, product: 435, ProductName: "yellow"}]

desired result:

[ 
 { 
  ID: 2775030, 
  name: "germany"
  Product [2] 
              {
              product: 458, 
              ProductName: "blue"
              },
              { product: 324, 
              ProductName: "green"
              }
  },
  {
   ID: 2775031, 
   name: "netherlands"
   Product [1] 
              {
              product: 435, 
              ProductName: "yellow"
              }
 }
]

this is where i got stuck, i am able to remove the product array as from database and i get both arrays, but i can't seem to push the product correctly inside the factory listing, so i get the new updated product factory listing, this is what i got

    var products = [{ID: 2775030, product: 458, ProductName: "blue"}, {ID: 2775030, product: 324, ProductName: "green"}, {ID: 2775031, product: 435, ProductName: "yellow"}]

    ListProductsAvailable(products)

    function ListProductsAvailable(products) {

        var F = [{ID: 2775030, name: "germany"},{ID: 2775031, name: "netherlands"}]

        var FP = products;

        // remove the Product from the existing array

        for (var i = 0; i < F.length; i++) {

            delete F[i].Product;

            if (i == F.length -1) {

                productFactorybuild(F)

            }
        }



  function productFactorybuild(F) {

  for (var i = 0; i < F.length; i++) {

            Product = [];
            for (var j = 0; j < FP.length; j++) {
                if (F[i].ID == FP[j].ID) {
                    Product.push
                        //PRODUCT
                        ({
                            product: FP[j].id_product,
                            ProductName: FP[j].ProductName,
                        })
                }
            }

            F.push(Product);

        }

        console.log(F) // THE DESIRED OUTPUT

    }

}
Ewald Bos
  • 1,560
  • 1
  • 20
  • 33

4 Answers4

0

You can use a mix of map and filter.

Basically map all your F array, and the use filter to build up the products..

eg.

var F = [{ID: 2775030, name: "germany"},{ID: 2775031, name: "netherlands"}];

var products = [{ID: 2775030, product: 458, ProductName: "blue"}, {ID: 2775030, product: 324, ProductName: "green"}, {ID: 2775031, product: 435, ProductName: "yellow"}]; 

const r = F.map(f=>({
  ...f,
  products: products.filter(p => p.ID === f.ID)
}));

console.log(r);
Keith
  • 22,005
  • 2
  • 27
  • 44
0
var F = [
{ID: 2775030, name: "germany"},
{ID: 2775031, name: "netherlands"}
];

var products = [{ID: 2775030, product: 458, ProductName: "blue"}, {ID: 2775030, product: 324, ProductName: "green"}, {ID: 2775031, product: 435, ProductName: "yellow"}];

 F.forEach((fact,i) => { 
 let filterData = products.filter(prd => prd.ID === fact.ID);
 F[i].products = filterData;
});

console.log(JSON.stringify(F));
uiTeam324
  • 1,215
  • 15
  • 34
0

Since your question has already been answered, I'm only adding this just for the case you can't use ECMA6 script (e.g. because you have to serve IE11):

You don't have to change much, you can push your products directly into your target-array:

function productFactorybuild(F) {

        for (var i = 0; i < F.length; i++) {

            for (var j = 0; j < FP.length; j++) {
                if (F[i].ID == FP[j].ID) {

                    if (!F[i].Product)
                        F[i].Product= [];

                    F[i].Product.push
                        //PRODUCT
                        ({
                            product: FP[j].id_product,
                            ProductName: FP[j].ProductName,
                        })
                }
            }
        }

        console.log(F) // THE DESIRED OUTPUT

    }
MelStuch
  • 21
  • 2
  • thanks for the answer. i was looking into the other proposed solution. What would the actual difference be in terms of speed? which one is faster to get the desired array? – Ewald Bos Mar 16 '20 at 14:29
  • I would guess that the map and filter functions suggested in the other solutions are faster, since they avoid the nested loops of your current code. But, as I said, just guessing. – MelStuch Mar 16 '20 at 14:45
  • @MelStuch your time complexity will be the same with `filter` method because in your code you are iterating over all arrays. `map()` and `filter()` will iterate through all arrays to get desired result. – StepUp Mar 16 '20 at 14:52
0

We can create an object which will store products grouped by ID. Grouping by ID can be done by reduce method:

const groupedProducts = products.reduce((a, c)=> {
    a[c.ID] = a[c.ID] || {products: []};
    a[c.ID].products.push(c);
    return a;
}, {});

and then just map your desired object and access to groupedProducts with O(1). Read more about big O notation:

const r = F.map(f=>({
  ...f,
  products: groupedProducts[f.ID] || []
}));

An example:

let F = [{ID: 2775030, name: "germany"},{ID: 2775031, name: "netherlands"}];

let products = [{ID: 2775030, product: 458, ProductName: "blue"}, 
    {ID: 2775030, product: 324, ProductName: "green"}, 
    {ID: 2775031, product: 435, ProductName: "yellow"}];

const groupedProducts = products.reduce((a, c)=> {
    a[c.ID] = a[c.ID] || {products: []};
    a[c.ID].products.push(c);
    return a;
}, {});

const r = F.map(f=>({
  ...f,
  products: groupedProducts[f.ID] || []
}));

console.log(r);
StepUp
  • 36,391
  • 15
  • 88
  • 148