-1

I am new to javascript so I am struggling to even know where to start. Please can someone help me.

I have this list of ingredients:

const Ingris = [
  {
    val: "onion,",
    amount: "1",
  },
  {
    val: "paprika",
    amount: "½ tsp",
  },
  {
    val: "yogurt",
    amount: "1/2 Cup",
  },
  {
    val: "fine sea salt",
    amount: "½ tsp  ",
  },
];

I want to categories them based on these variables below:

var spices = ["paprika", "parsley", "peppermint", "poppy seed", "rosemary"];
var meats = ["steak", "ground beef", "stewing beef", "roast beef", "ribs"];
var dairy = ["milk", "eggs", "cheese", "yogurt"];
var produce = ["peppers", "radishes", "onions", "tomatoes"];

This is what I am trying to obtain:

// desired output:

const ShoppingList = [
  {
    produceOutput: [
      {
        val: "garlic, minced",
        amount: "8 cloves ",
      },
    ],
    spicesOutput: [
      {
        val: "paprika",
        amount: "½ tsp  ",
      },
      {
        val: "onion",
        amount: "1",
      },
    ],
    NoCategoryOutput: [
      {
        val: "fine sea salt",
        amount: "½ tsp",
      },
    ],
  },
];
Dilhan Bhagat
  • 408
  • 1
  • 10
  • 20
  • I am just trying to learn JavaScript for my own personal project. If you are willing to help me I'd really appreciate it – Dilhan Bhagat Sep 13 '20 at 20:44
  • It is kind of customary here that you present the code you have tried and have issues with, so we can have a look at it, fix it or come up with alternatives. – Carsten Massmann Sep 13 '20 at 20:52
  • @ I would do that , if I know how to do it . I can't post anything I've tried if I don't even know what to do – Dilhan Bhagat Sep 13 '20 at 20:59
  • at all ... this problem was tackled again by this Q. ... [*"How does one categorize a list of data items via many different category lists where each list contains several distinct category values?"*](https://stackoverflow.com/questions/63884077/how-does-one-categorize-a-list-of-data-items-via-many-different-category-lists-w) – Peter Seliger Sep 18 '20 at 09:54

4 Answers4

1

You can use a basic reducer for this kind of operation.

const categorizedOutput = Ingris.reduce((acc, cur) => {
  if (spices.includes(cur.val)) {
    acc.spices.push(cur);
  } else if (meats.includes(cur.val)) {
    acc.meats.push(cur);
  } else if (dairy.includes(cur.val)) {
    acc.dairy.push(cur);
  } else if (produce.includes(cur.val)) {
    acc.produce.push(cur);
  } else {
    acc.other.push(cur);
  }
  return acc;
}, {
  spices: [],
  meats: [],
  dairy: [],
  produce: [],
  other: []
})
Berk Kurkcuoglu
  • 1,453
  • 1
  • 9
  • 11
1

As everyone else here suggests using modern reduce, includes or forEach methods of arrays... just in case you need to support older browsers, or just more "classic" implementation, you may use a simple for loop with indexOf array-method.

const Ingris = [{ val: "onion,", amount: "1", },
  { val: "paprika", amount: "½ tsp",  },
  { val: "yogurt", amount: "1/2 Cup", },
  { val: "fine sea salt", amount: "½ tsp  ", },
];
var spices = ["paprika", "parsley", "peppermint", "poppy seed", "rosemary"];
var meats = ["steak", "ground beef", "stewing beef", "roast beef", "ribs"];
var dairy = ["milk", "eggs", "cheese", "yogurt"];
var produce = ["peppers", "radishes", "onions", "tomatoes"];

ShoppingList = {
  produceOutput: [],
  spicesOutput: [],
  meatsOutput: [],
  dairyOutput: [],
  NoCategoryOutput: [],
};

for (var i = 0; i < Ingris.length; i++) {
  var ingredient = Ingris[i];
  if (spices.indexOf(ingredient.val) >= 0) {
    ShoppingList.spicesOutput.push(ingredient);
  } else if (meats.indexOf(ingredient.val) >= 0) {
    ShoppingList.meatsOutput.push(ingredient);
  } else if (dairy.indexOf(ingredient.val) >= 0) {
    ShoppingList.dairyOutput.push(ingredient);
  } else if (produce.indexOf(ingredient.val) >= 0) {
    ShoppingList.produceOutput.push(ingredient);
  } else {
    ShoppingList.NoCategoryOutput.push(ingredient);
  }
}

console.log(ShoppingList)

Also take in mind that if in Ingris there are some repeating ingredients - they will not sum up their amounts. To be able to do so, you would need to provide or convert each amount in some numeric format, for example decimal number. Also instead of simple push there would be some additional logic checking if current ingredient is already in the list and in the case it is - adding their amounts.

mplungjan
  • 169,008
  • 28
  • 173
  • 236
dmikam
  • 992
  • 1
  • 18
  • 27
0

var spices  = ["paprika", "parsley", "peppermint", "poppy seed", "rosemary"];
var meats   = ["steak", "ground beef", "stewing beef", "roast beef", "ribs"];
var dairy   = ["milk", "eggs", "cheese", "yogurt"];
var produce = ["peppers", "radishes", "onions", "tomatoes"];

var ingredients=[
  {"val":"onion,"       , "amount":"1"},
  {"val":"paprika"      , "amount":"½ tsp"},
  {"val":"yogurt"       , "amount":"1/2 Cup"},
  {"val":"fine sea salt", "amount":"½ tsp"}
];

var shoppingList={spices:[], meats:[], dairy:[], produce:[], other:[]};

ingredients.forEach(ingredient=>{
  if(spices.includes(ingredient.val)) shoppingList.spices.push(ingredient);
  else if(meats.includes(ingredient.val)) shoppingList.meats.push(ingredient);
  else if(dairy.includes(ingredient.val)) shoppingList.dairy.push(ingredient);
  else if(produce.includes(ingredient.val)) shoppingList.produce.push(ingredient);
  else shoppingList.other.push(ingredient);
});

console.log(shoppingList);
iAmOren
  • 2,760
  • 2
  • 11
  • 23
0

Here is a slightly more parametric way of doing it. I combined the different food categories into one object cat and allow for partial matches of the ingredients (singular matches plural):

const cat={ 
  spices: ["paprika", "parsley", "peppermint", "poppy seed", "rosemary","fine sea salt"],
  meats: ["steak", "ground beef", "stewing beef", "roast beef", "ribs"],
  dairy: ["milk", "eggs", "cheese", "yogurt"],
  produce: ["peppers", "radishes", "onions", "tomatoes"]};

var ingredients=[
  {"val":"onion"       , "amount":"1"},
  {"val":"paprika"      , "amount":"½ tsp"},
  {"val":"yogurt"       , "amount":"1/2 Cup"},
  {"val":"fine sea salt", "amount":"½ tsp"}
];

const shop=ingredients.reduce((acc,ing)=>{
  Object.entries(cat).some(([ca,pr])=>
    pr.find(p=>p.indexOf(ing.val)>-1) && 
    (acc[ca]=acc[ca]||[]).push(ing) )
  || (acc.other=acc.other||[]).push(ing);
  return acc;
}, {});
console.log(shop);
Carsten Massmann
  • 26,510
  • 2
  • 22
  • 43