0

I am new to JavaScript so I am struggling to even know where to start. Please can someone help me. I have this array of ingredients:

const ingris =  [
  "1 cup heavy cream",
  "8 ounces paprika",
  "1 Chopped Tomato",
  "1/2 Cup yogurt",
  "1 packet pasta ",
  "1/2 teaspoon freshly ground black pepper, divided",
]

I am trying to take out for example the 1 cup or 1/2 teaspoon (first 2 words of the array) and add it to a new array of objects like below:

const ShoppingList = [
  {
    val: "heavy cream",
    amount: "1 cup",
  },
  {
    val: "Tomato",
    amount: "1 Chopped ",
  },
  {
    val: "yogurt",
    amount: "1/2 Cup",
  },
];
norbitrial
  • 14,716
  • 7
  • 32
  • 59
Dilhan Bhagat
  • 408
  • 1
  • 10
  • 20
  • 2
    Break down your big problem into smaller problems. Have you searched ["javascript get first 2 words" on Google](https://www.google.com/search?q=javascript+get+first+2+words)? – blex Sep 13 '20 at 18:18
  • You can use the split function in a loop to go through all your array elements then grabbing the spilt array and adding the two first elements to the object. – Souhailhimself Sep 13 '20 at 18:19
  • @blex Yes but this is an array not an individual string – Dilhan Bhagat Sep 13 '20 at 18:19
  • @Souhailhimself Please can you post an answer because I have no idea how to do that. I would really appreciate all the help you can give me !!!!!! – Dilhan Bhagat Sep 13 '20 at 18:20
  • It won't work for the pepper... For tomato, "1" is appropriate - more than "1 chopped". You'd need to write a language parser... Split into Quantities, Measurements, Items and bunch the rest (if any) to Comments: `1/2 teaspoon freshly ground black pepper, divided` => [`1/2`, `teaspoon`], `black pepper`, `freshly ground, divided`... It can be done, but it's a lot of work. Perhaps there is something out there for this - but I'd welcome the challenge to code it myself! – iAmOren Sep 13 '20 at 18:20
  • Yes, but now, you know how to do it for a single string. The only thing you have left to figure out is how to loop though an Array – blex Sep 13 '20 at 18:21
  • @iAmOren If you can do that you are a genius!!!!!!! Because I didn't mind having the `freshly ground, divided` but if it can be separated like that please help me I am really struggling – Dilhan Bhagat Sep 13 '20 at 18:23
  • @Souhailhimself: `split(" ")`.... – iAmOren Sep 13 '20 at 18:24
  • Dilhan, you will have to pay me for that - and a lot! :) – iAmOren Sep 13 '20 at 18:24
  • Correction: It WOULD work for the pepper, just the rest won't be just "pepper"... Still, logic fails for tomato... – iAmOren Sep 13 '20 at 18:28
  • @Souhailhimself, on my machine, chrome/windows, `split()` returns an array of one element = the whole string... – iAmOren Sep 13 '20 at 18:30
  • "If separator is omitted or does not occur in str, the returned array contains one element consisting of the entire string." - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split – iAmOren Sep 13 '20 at 18:32
  • @iAmOren That's true my bad I confused it with split in python. – Souhailhimself Sep 13 '20 at 18:34
  • @Souhailhimself yeah! It caused me so many headaches... – iAmOren Sep 13 '20 at 18:47
  • at all ... this problem was tackled again by this Q. ... [*"How does one parse best each item of an ingredient list and does create a new object based on each parsing result?"*](https://stackoverflow.com/questions/63880334/how-does-one-parse-best-each-item-of-an-ingredient-list-and-does-create-a-new-ob) – Peter Seliger Sep 18 '20 at 09:58

3 Answers3

3

Probably I would try to use .map() first iterate through the array of strings and convert it into an new array of objects. On each iteration you can .split() the string by spaces and most probably the first 2 elements of the array can be the amount property and the rest is the value.

See from the documentations:

The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.

The split() method divides a String into an ordered list of substrings, puts these substrings into an array, and returns the array. The division is done by searching for a pattern; where the pattern is provided as the first parameter in the method's call.

Try as the following:

const ingris = [
  "1 cup heavy cream",
  "8 ounces paprika",
  "1 Chopped Tomato",
  "1/2 Cup yogurt",
  "1 packet pasta",
  "1/2 teaspoon freshly ground black pepper, divided",
];

const result = ingris.map(e => {
  const split = e.split(' ');
  const amount = `${split[0]} ${split[1]}`;
  
  return { val: e.replace(`${amount} `, ''), amount };
});

console.log(result);

Probably you need to add fallback once you have different format of input strings, like checking if you have at least 3 words in that string.

norbitrial
  • 14,716
  • 7
  • 32
  • 59
1

Using Array#map to map the given array to a new one. Split the string to an arry at the spaces. return a new object with the first 2 array-elements as val and the others as amount. For gettuing the last elements use Array#slice and Array#join with a space as glue to connect them to a string.

const ingris =  [
  "1 cup heavy cream",
  "8 ounces paprika",
  "1 Chopped Tomato",
  "1/2 Cup yogurt",
  "1 packet pasta ",
  "1/2 teaspoon freshly ground black pepper, divided",
];

let result = ingris.map(str => {
    let arr = str.split(' ');
    return {val: arr[0] + ' ' + arr[1], amount: arr.slice(2).join(' ')};
});

console.log(result);
Sascha
  • 4,576
  • 3
  • 13
  • 34
0

There are multiple approach but using Array.prototype.map to loop over the array, String.prototype.split to turn each string into a array inside the loop, Array.prototype.slice() to get a slice from the array will help you create what you need. But keep in mind that it currently always get the first 2 words and the words after that. So your ingredients have to be the same way every time

const ingris =  [
  "1 cup heavy cream",
  "8 ounces paprika",
  "1 Chopped Tomato",
  "1/2 Cup yogurt",
  "1 packet pasta ",
  "1/2 teaspoon freshly ground black pepper, divided",
];

const shoppingList = ingris.map(ingredient => {
  const splitIngredient = ingredient.split(' ');
  const amount = splitIngredient.slice(0, 2).join(' ');
  const val = splitIngredient.slice(2, splitIngredient.length).join(' ');
  return { val, amount };
});

console.log(shoppingList);
Emiel Zuurbier
  • 19,095
  • 3
  • 17
  • 32