Javascript array with JSON object

Asked

Viewed 87 times

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 intend 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 am a while away to work on it 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);

I appreciate a help.

1 answer

1


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

Start by checking if the first category plays with the first category of the first product:

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

This 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;

Which had previously been declared entraP and not entrarP.

But the logic itself would not work either because the while executes as long as the categories are equal:

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

Soon as one is different this ends immediately.

As a solution you can use javascript’s reduce function to "reduce" 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 only 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);

  • thanks for the help. Works perfectly.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.