JavaScript Array with JSON object

0

I have the following objects:

var category = [
    {"category" : "fruity"},
    {"category" : "Cakes"}
]

and

var products = [
    {"description" : "Apple", "price" : 12.99, "category" : "Fruity"},
    {"description" : "Peach", "price" : 12.99, "category" : "Fruity"},
    {"description" : "Cake one", "price" : 12.99, "category" : "Cake"}
]

I want to make this information available in the following format:

[
    {
        "category": "fruity",
        "products": [
            {
                "description" : "Apple",
                "price" : 12.99
            },
            {
                "description" : "Peach",
                "price" : 17.99
            }
        ]
    },
    {
        "category": "Cakes",
        "products": [
            {
                "description" : "Cake one",
                "price" : 12.99
            }
        ]
    }
]

I'm working on this at one time and the result has not been satisfactory. Here is my code:

var j=0;
var i=0;
var entraP = { prod : [] }

if (category[i].category == products[j].category ){

  entrarP.c = category[i].category;

  while(category[i].category == products[j].category ){

    entrarP.prod.push(products[j]);

    j+=1;
  }
  i+=1;
}

console.log(entrarP);

Thank you for your help.

    
asked by anonymous 01.09.2017 / 00:38

1 answer

1

The code that you are using to try to group the products has some things that you do not play for the purpose.

Starts by checking whether the first category plays with the first category of the first product:

if (category[i].category == products[j].category ){

What makes it impossible to group if the products appear in another order.

There is also an error in the name of the variable that gets the result:

entrarP.c = category[i].category;

That had previously been declared as entraP and not entrarP .

But the logic itself also would not work because while executes while the categories are equal:

while(category[i].category == products[j].category ){

As soon as one is different, it ends immediately.

As a workaround, you can use the javascript reduce function to "shrink" the original array of products according to their categories, as follows:

var produtosAgrupados = products.reduce(function(acumulador, corrente){

  //verificar se o acumulador(o resultado) já tem a categoria corrente obtendo a sua posição
  let indice = acumulador.map(x => x.category).indexOf(corrente.category);

  //-1 indica que não tem logo cria um novo objeto com categoria e produtos com 1, o corrente
  if (indice==-1){
    acumulador.push({
      category: corrente.category, 
      products: [{  
        description:corrente.description, 
        price:corrente.price}]
    });
  }
  else { //se ja tem a categoria adiciona nessa posição o novo produto
    acumulador[indice].products.push({  
        description:corrente.description, 
        price:corrente.price});
  }

  return acumulador; //retorna o objeto corrente para a próxima iteração
},[]); //começa o reduce com um array vazio

For this solution the original array that had just the categories would not even be needed.

Example:

var products = [
    {"description" : "Apple", "price" : 12.99, "category" : "Fruity"},
    {"description" : "Peach", "price" : 12.99, "category" : "Fruity"},
    {"description" : "Cake one", "price" : 12.99, "category" : "Cake"}
];

var produtosAgrupados = products.reduce(function(acumulador, corrente){

  let indice = acumulador.map(x => x.category).indexOf(corrente.category);

  if (indice==-1){
    acumulador.push({
      category: corrente.category, 
      products: [{  
        description:corrente.description, 
        price:corrente.price}]
    });
  }
  else {
    acumulador[indice].products.push({  
        description:corrente.description, 
        price:corrente.price});
  }
  
  return acumulador;
},[]);

console.log(produtosAgrupados);
    
01.09.2017 / 01:30