首頁  >  文章  >  web前端  >  一份(不)可變的美味香蒜義大利麵購物清單

一份(不)可變的美味香蒜義大利麵購物清單

王林
王林原創
2024-08-21 09:01:02419瀏覽

An (Im)mutable Shopping List for a Delicious Pesto Pasta

香蒜醬義大利麵證明上帝存在

生活中沒有什麼比在自製的卡佩里尼(天使發)上享用大量新鮮香蒜醬更讓我高興的了。我是一個真正的美食家 - 尤其是在意大利美食方面 - 並且總是嘗試更複雜的食譜,但這種極簡主義菜餚的簡單性和享受永遠不會停止滿足。如果我有幸選擇最後一頓飯,那麼在壽司和香蒜醬和意大利麵之間做出艱難的決定將是一個艱難的決定,但我仍然認為香蒜意大利麵最終勝出。

所有關於香蒜醬的討論都讓我很餓

我該怎麼辦?好吧,當然是做香蒜義大利麵。有時你只需說:「Quando a Roma!」

讓我們先列出從我們友善的義大利市場「Il Mercato di Giovanni」購買的食材清單。我們將使用不可變和可變物件陣列從兩個食譜建立購物清單。雖然簡單地寫出我們需要的東西會更有效,但你知道這更有趣。我可以告訴你渴望了解更多關於如何編程製作香蒜醬意大利麵的信息,所以讓我們挖掘。 「Mangia Mangia!」

創建單獨的意大利麵和香蒜醬食譜數組

我們首先聲明 PastaRecipeArray 和 pestoRecipeArray 的變量,每個變數分配給一個物件數組,其中每個物件代表一種單獨的成分。

當我們為每個變數分配數組值時,我們使用 Object.freeze() 方法來確保它們是不可變的。 (稍後再詳細介紹)

每個食譜物件都有三個屬性,鍵值對如下:

  • '名稱' = “字串”形式的成分名稱
  • 'recipe' = 一個或多個值,以「數組」的形式表示,指示哪種配方需要該成分(意大利麵、香蒜醬或兩者)
  • '價格' = 成分的美元價格,以「數字」的形式,使用相當不切實際的虛擬內容

(注意:我在這篇文章中省略了數量和其他細節,以使事情簡短且相對簡單。我們也可以使用JSON 來實現這些對象,但我們讓事情易於消化 此處。 建立這些陣列的程式碼將如下所示:


您會再次注意到配方鍵指向一個陣列形式的值。我們這樣設定是因為兩個食譜中都使用了一些食材。
const pastaRecipeArray = Object.freeze([
  { "name": "Eggs", "recipe": ["pasta"], "price": 6.99 },
  { "name": "Extra Virgin Olive Oil", "recipe": ["pasta", "pesto"], "price": 12.59 },
  { "name": "Kosher Salt", "recipe": ["pasta", "pesto"], "price": 7.89 },
  { "name": "Semolina Flour", "recipe": ["pasta"], "price": 12.95 }
])

const pestoRecipeArray = Object.freeze([
  { "name": "Basil", "recipe": ["pesto"], "price": 6.99 },
  { "name": "Black Pepper", "recipe": ["pesto"], "price": 9.99 },
  { "name": "Extra Virgin Olive Oil", "recipe": ["pasta", "pesto"], "price": 12.59 },
  { "name": "Kosher Salt", "recipe": ["pasta", "pesto"], "price": 7.89 },
  { "name": "Parmesan", "recipe": ["pesto"], "price": 15.99 },
  { "name": "Pine Nuts", "recipe": ["pesto"], "price": 13.98 }
])

為了測試 PastaRecipeArray 是否正確設置,我們可以利用 .forEach() 方法,這是用於迭代數組中每個物件的回調函數。使用成分作為參數,我們可以將其登入控制台,如下所示:


當您檢查控制台時,您應該看到類似以下輸出的內容:
pastaRecipeArray.forEach((ingredient) => {
  console.log(ingredient)
})


類似地,我們可以像這樣記錄我們的pestoRecipeArray:
Object {name: "Eggs", recipe: Array(1), price: 6.99}
Object {name: "Extra Virgin Olive Oil", recipe: Array(2), price: 12.59}
Object {name: "Kosher Salt", recipe: Array(2), price: 7.89}
Object {name: "Semolina Flour", recipe: Array(1), price: 12.95}


結果如下:
pestoRecipeArray.forEach((ingredient) => {
  console.log(ingredient)
})


Object {name: "Basil", recipe: Array(1), price: 6.99}
Object {name: "Black Pepper", recipe: Array(1), price: 9.99}
Object {name: "Extra Virgin Olive Oil", recipe: Array(2), price: 12.59}
Object {name: "Kosher Salt", recipe: Array(2), price: 7.89}
Object {name: "Parmesan", recipe: Array(1), price: 15.99}
Object {name: "Pine Nuts", recipe: Array(1), price: 13.98}
(注意:當您看到Array(1) 和Array(2) 等輸出時,您可能想要重寫函數來選擇這些鍵,或者只需單擊控制台中的數組即可查看詳細資訊它包含什麼。

建立購物清單數組 現在我們已經建立了食譜數組,我們想要繼續下一步,建立一個購物清單數組。為此,我們需要將物件數組 PastaRecipeArray 和 pestoRecipeArray 組合到一個名為 shoppingListArray 的新可變變數中。我們將使用擴充運算子來做到這一點......就像這樣:

現在讓我們使用下面的 console.log() 來看看我們的新清單是什麼樣子的。展望未來,我們將記錄對象內的屬性值而不是整個對象,以消除一些混亂。您將需要使用此程式碼來查看我們的清單在流程的每個步驟之後如何變更。

const shoppingListArray = [...pastaRecipeArray, ...pestoRecipeArray]

我們可以看到我們的清單已在控制台中合併為一個,這次僅記錄每種成分名稱。

shoppingListArray.forEach((ingredient) => {
      console.log(ingredient.name)
})

不可變數組與可變數組

為什麼我們應該讓 PastaRecipeArray 和 pestoRecipeArray 不可變?使它們不可變使得我們在分配它們後無法更改它們的值。我們不想撕毀這些食譜。我們希望拯救他們,迎接另一個輝煌的一天。無論我們要在臨時的、可變的購物清單上寫什麼,這些一成不變的家庭食譜都需要繼續下去。
Eggs
Extra Virgin Olive Oil
Kosher Salt
Semolina Flour
Basil
Black Pepper
Extra Virgin Olive Oil
Kosher Salt
Parmesan
Pine Nuts

我們還希望能夠從新創建的 shoppingListArray 中添加或刪除成分,以使這道菜符合我們的特定口味,當然不會影響我們原來的食譜。

Adding, replacing, and deleting ingredients

As you may have noticed, when we combined our pasta and pesto recipes into our shopping list we ended up with duplicates for "Extra Virgin Olive Oil" and "Kosher Salt". We don't need to buy these twice so let's get rid of them. There are fancier ways to eliminate duplicates, but for now we will use .splice() to remove the first Extra Virgin Olive Oil object.

The .splice() method destructively deletes or replaces elements in an array. The first parameter represents the first element we are deleting and the second parameter represents how many elements we want to delete from that start point. While "Extra Virgin Olive Oil" is the second object in the array, arrays start at '0', so technically the second object is represented by a '1'. Let's execute the following:

shoppingListArray.splice(1, 1)

In the console you will see that there is now only one "Extra Virgin Olive Oil" object. (note: If you try to use .splice() or similar methods on one of our original recipe arrays you will get a TypeError because we used Object.freeze(), making them immutable.)

We still have an extra "Kosher Salt", and now we are going to use .splice() to it's full power. In addition to our first two parameters we have a third parameter that can replace elements in an array with new elements. I love to add a bit of lemon to my pesto, and I don't like food that is too salty, so let's go ahead and replace our extra "Kosher Salt" with our new "Lemon" object. We will declare our lemon object as a variable for better readibility and include it as the third .splice() parameter.

const lemon = { "name": "Lemon", "recipe": ["pesto"], "price": 2.04 }

shoppingListArray.splice(6, 1, lemon)

Today I'm feeling a bit saucy so let's change things up a bit and add in some roasted tomatoes using .push(). With .push() we can add elements to the end of the array, with each parameter representing a new element. So let's add some "Cherry Tomatoes" to our list. Come to think of it, I forgot the "Garlic" too!

const tomatoes = { "name": "Cherry Tomatoes", "recipe": ["pesto"], "price": 5.99 }

const garlic = { "name": "Garlic", "recipe": ["pesto"], "price": 2.99 }

shoppingListArray.push(tomatoes, garlic)

Organizing our shopping list

Now that we have all our ingredients well established let's organize them in a way that will make our shopping experience seamless.

Let's organize our list alphabetically using .sort().

shoppingListArray.sort((a, b) => {
  const nameA = a.name
  const nameB = b.name

  if (nameA < nameB) {
    return -1
  }
  if (nameA > nameB) {
    1
  }
  return 0
})

Our shopping list now looks like this in the console.

Basil
Black Pepper
Cherry Tomatoes
Eggs
Extra Virgin Olive Oil
Garlic
Kosher Salt
Lemon
Parmesan
Pine Nuts
Semolina Flour

Planning ahead for our expected costs

Now we are ready to go to the market, but first let's make sure we know how much money we need, using .reduce(). There is a lot to go over with .reduce(), and I'm getting hungry, so I'll skip over the details.

const ingredientsPrice = shoppingListArray.reduce((accumulator, ingredient) => {
  return accumulator + ingredient.price
}, 0)

console.log("You will need $" + ingredientsPrice + " to make pesto pasta. Man is life is expensive.")
// You will need $98.39 to make pesto pasta. Wow, life is expensive.

Creating new recipe list arrays

So we went to the store and got our ingredients, but now we want to separate our ingredients back into their respective recipes, just to lay everything out on the table and keep things in order. Lets create two new arrays, pastaIngredients and pestoIngredients using .filter(), .includes(), and of course .forEach() to log them to the console.

const pastaIngredients = shoppingListArray.filter((ingredient) => {
  return ingredient.recipe.includes('pasta')
})

pastaIngredients.forEach((ingredient) => {
  console.log(ingredient.name)
})
const pestoIngredients = shoppingListArray.filter((ingredient) => {
  return ingredient.recipe.includes('pesto')
})

pestoIngredients.forEach((ingredient) => {
  console.log(ingredient.name)
})

"Wrapping" it up

As you can see from logging these to the console we successfully created a shoppingListArray that didn't modify our original immutable recipe arrays, pastaRecipeArray and pestoRecipeArray. We then were able to mutably modify the shoppingListArray in a destructive manner to add, delete, and replace ingredients to our liking. We also calculated how much we needed to spend before going to the store. Lastly, we were able to separate these ingredients back into their respective recipes, pastaIngredients and pestoIngredients in preparation for a brilliant meal.

Well, what a delicious dish that was. I hope you enjoyed it as much as I did. Again, Mangia Mangia!

以上是一份(不)可變的美味香蒜義大利麵購物清單的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn