」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 一份(不)可變的美味香蒜醬義大利麵購物清單

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

發佈於2024-08-22
瀏覽:826

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)
})

当您检查控制台时,您应该看到类似以下输出的内容:

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:

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 的新可变变量中。我们将使用扩展运算符来做到这一点......就像这样:

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

现在让我们使用下面的 console.log() 来看看我们的新列表是什么样子的。展望未来,我们将记录对象内的属性值而不是整个对象,以消除一些混乱。您将需要使用此代码来查看我们的列表在流程的每个步骤之后如何变化。

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

我们可以看到我们的列表已在控制台中合并为一个,这次仅记录每种成分名称。

Eggs
Extra Virgin Olive Oil
Kosher Salt
Semolina Flour
Basil
Black Pepper
Extra Virgin Olive Oil
Kosher Salt
Parmesan
Pine Nuts

不可变数组与可变数组

为什么我们应该使 PastaRecipeArray 和 pestoRecipeArray 不可变?使它们不可变使得我们在分配它们后无法更改它们的值。我们不想撕毁这些食谱。我们希望拯救他们,迎接另一个辉煌的一天。无论我们要在临时的、可变的购物清单上写什么,这些一成不变的家庭食谱都需要继续下去。

我们还希望能够从新创建的 shoppingListArray 中添加或删除成分,以使这道菜符合我们的特定口味,当然不会影响我们原来的食谱。

添加、替换和删除成分

正如您可能已经注意到的,当我们将意大利面和香蒜酱食谱合并到购物清单中时,我们最终得到了“特级初榨橄榄油”和“犹太盐”的重复项。我们不需要两次购买这些东西,所以我们把它们扔掉吧。有一些更奇特的方法可以消除重复项,但现在我们将使用 .splice() 来删除第一个特级初榨橄榄油对象。

.splice() 方法会破坏性地删除或替换数组中的元素。第一个参数表示我们要删除的第一个元素,第二个参数表示我们要从该起点删除多少个元素。虽然“Extra Virgin Olive Oil”是数组中的第二个对象,但数组从“0”开始,因此从技术上讲,第二个对象由“1”表示。让我们执行以下命令:

shoppingListArray.splice(1, 1)

在控制台中,您将看到现在只有一个“Extra Virgin Olive Oil”对象。 (注意:如果您尝试在我们的原始配方数组之一上使用 .splice() 或类似方法,您将收到 TypeError,因为我们使用了 Object.freeze(),使它们不可变。)

我们还有额外的“犹太盐”,现在我们将充分利用 .splice() 的功能。除了前两个参数之外,我们还有第三个参数,可以用新元素替换数组中的元素。我喜欢在香蒜酱中添加一点柠檬,而且我不喜欢太咸的食物,所以让我们继续用新的“柠檬”对象替换多余的“犹太盐”。我们将把柠檬对象声明为变量以提高可读性,并将其作为第三个 .splice() 参数。

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

shoppingListArray.splice(6, 1, lemon)

今天我感觉有点俏皮所以让我们稍微改变一下并使用 .push() 添加一些烤西红柿。使用 .push() 我们可以将元素添加到数组末尾,每个参数代表一个新元素。 因此,让我们在列表中添加一些“樱桃番茄”。想想看,我也忘记了“大蒜”!

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

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

shoppingListArray.push(tomatoes, garlic)

整理我们的购物清单

现在我们已经掌握了所有的成分,让我们以一种使我们的购物体验无缝的方式组织它们。

让我们使用 .sort() 按字母顺序组织列表。

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

  if (nameA  nameB) {
    1
  }
  return 0
})

我们的购物清单现在在控制台中看起来像这样。

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

提前规划我们的预期成本

现在我们准备进入市场,但首先让我们使用 .reduce() 确保知道我们需要多少钱。 .reduce() 有很多东西需要讨论,而且我饿了,所以我将跳过细节。

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.

创建新的配方列表数组

所以我们去商店买了原料,但现在我们想将原料重新分成各自的食谱,只是为了将所有东西都放在桌子上并保持秩序。让我们使用 .filter()、.includes() 创建两个新数组,pastaIngredients 和 pestoIngredients,当然还有 .forEach() 将它们记录到控制台。

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)
})

“包裹”起来

正如您将这些记录到控制台所看到的,我们成功创建了一个 shoppingListArray,它没有修改我们原来的不可变食谱数组、pastaRecipeArray 和 pestoRecipeArray。然后,我们能够以破坏性的方式可变地修改 shoppingListArray,以根据我们的喜好添加、删除和替换成分。我们还计算了去商店之前需要花多少钱。最后,我们能够将这些成分分离回各自的食谱、面食成分和香蒜酱成分中,为一顿丰盛的大餐做好准备。

嗯,那是多么美味的。我希望你和我一样喜欢它。 再次,Mangia Mangia!

版本聲明 本文轉載於:https://dev.to/lakadaize/an-immutable-shopping-list-for-a-delicious-pesto-pasta-2jd6?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • 如何在 Laravel 中執行 Cron 作業
    如何在 Laravel 中執行 Cron 作業
    在本教程中,我將向您展示如何在 Laravel 中運行 cron 作業,但最重要的是,我們會讓事情對我們的學生來說簡單易行。在建立 Laravel 應用程式時,我們將探索如何在您自己的電腦上設定和執行這些自動化任務。 首先,什麼是 cron 作業?將其視為您網站的私人助理 - 一個從不睡覺並且總是...
    程式設計 發佈於2024-11-05
  • 填滿如何影響內聯元素的間距以及如何解決衝突?
    填滿如何影響內聯元素的間距以及如何解決衝突?
    內聯元素上的填充:效果和限制內聯元素上的填充:效果和限制根據源碼,在內聯元素的頂部和底部添加內邊距並不影響周圍元素的間距。然而,「填充將與其他內聯元素重疊」這一說法表明,在某些特定情況下,填充確實會產生影響。 了解重疊填充填充主要影響它應用於的元素,增加其垂直邊框。在正常情況下,這不會導致與相鄰的內...
    程式設計 發佈於2024-11-05
  • Django 基於類別的視圖變得簡單
    Django 基於類別的視圖變得簡單
    眾所周知,django在開發Web應用程式時使用MVT(模型-視圖-模板)進行設計。 View 本身是一個可呼叫的,它接受請求並回傳回應。它不僅僅是一個函數,因為 Django 提供了一種稱為「基於類別的視圖」的東西,因此開發人員可以使用基於類別的方法或您可以說 OOP 方法來編寫視圖。這個基於類...
    程式設計 發佈於2024-11-05
  • 使用 VAKX 建立您的無程式碼 AI 代理
    使用 VAKX 建立您的無程式碼 AI 代理
    If you’ve been keeping up with the AI space, you already know that AI agents are becoming a game-changer in the world of automation and customer inter...
    程式設計 發佈於2024-11-05
  • 這裡是我如何在 jQuery Datatable 中實作基於遊標的分頁。
    這裡是我如何在 jQuery Datatable 中實作基於遊標的分頁。
    在 Web 應用程式中處理大型資料集時,分頁對於效能和使用者體驗至關重要。標準的基於偏移量的分頁(通常與資料表一起使用)對於大型資料集可能效率低。 基於遊標的分頁提供了一種效能更高的替代方案,特別是在處理即時更新或大量資料載入時。在本文中,我將引導您了解如何在 jQuery DataTable 中...
    程式設計 發佈於2024-11-05
  • 為什麼同步引擎可能是 Web 應用程式的未來
    為什麼同步引擎可能是 Web 應用程式的未來
    在不断发展的 Web 应用程序世界中,效率、可扩展性和无缝实时体验至关重要。传统的 Web 架构严重依赖于客户端-服务器模型,这些模型可能难以满足现代对响应能力和同步的需求。这就是同步引擎发挥作用的地方,它为开发人员当今面临的许多挑战提供了一个有前途的解决方案。但同步引擎到底是什么?为什么它们可能是...
    程式設計 發佈於2024-11-05
  • Python 電腦視覺簡介(第 1 部分)
    Python 電腦視覺簡介(第 1 部分)
    注意:在这篇文章中,我们将仅使用灰度图像以使其易于理解。 什么是图像? 图像可以被认为是值的矩阵,其中每个值代表像素的强度。图像格式主要分为三种类型: Binary:此格式的图像由值为 0(黑色)和 1(白色)的单个二维矩阵表示。这是最简单的图像表示形式。 Grey-Scale:在此...
    程式設計 發佈於2024-11-05
  • 網站 HTML 程式碼
    網站 HTML 程式碼
    我一直在嘗試建立一個與航空公司相關的網站。我只是想確認我是否可以使用人工智慧生成程式碼來產生整個網站。 HTML 網站是否相容於博客,或者我應該使用 JavaScript?這是我用作演示的程式碼。 <!DOCTYPE html> <html lang="en">[](url...
    程式設計 發佈於2024-11-05
  • 像程式設計師一樣思考:學習 Java 基礎知識
    像程式設計師一樣思考:學習 Java 基礎知識
    本文介紹了 Java 程式設計的基本概念和結構。它首先介紹了變數和資料類型,然後討論了操作符和表達式,以及控制流程。其次,它解釋了方法和類,然後介紹了輸入和輸出操作。最後,本文透過一個工資計算器的實際範例展示了這些概念的應用。 像程式設計師一樣思考:掌握Java 基礎1. 變數與資料型別 ]Java...
    程式設計 發佈於2024-11-05
  • PHP GD 可以比較兩個影像的相似性嗎?
    PHP GD 可以比較兩個影像的相似性嗎?
    PHP GD 可以確定兩個影像的相似度嗎? 正在考慮的問題詢問是否可以使用以下命令確定兩個圖像是否相同PHP GD 通過比較它們的差異。這需要獲取兩個影像之間的差異並確定它是否完全由白色(或任何統一的顏色)組成。 根據所提供的答案,雜湊函數(如其他回應所建議的)不適用於此情境。比較必須涉及圖像內容而...
    程式設計 發佈於2024-11-05
  • 使用這些鍵編寫進階測試(JavaScript 中的測試需求)
    使用這些鍵編寫進階測試(JavaScript 中的測試需求)
    在本文中,您將學習每個高級開發人員都應該了解的 12 個測試最佳實踐。您將看到 Kent Beck 的文章“Test Desiderata”的真實 JavaScript 範例,因為他的文章是用 Ruby 編寫的。 這些屬性旨在幫助您編寫更好的測試。了解它們還可以幫助您在下一次工作面試中取得好成績。...
    程式設計 發佈於2024-11-05
  • 透過將 matlab/octave 演算法移植到 C 來實現 AEC 的最佳解決方案
    透過將 matlab/octave 演算法移植到 C 來實現 AEC 的最佳解決方案
    完畢!對自己有點印象。 我們的產品需要迴聲消除功能,確定了三種可能的技術方案, 1)利用MCU偵測audio out和audio in的音訊訊號,編寫演算法計算兩側聲音訊號的強度,根據audio out和audio in的強弱在兩個通道之間進行可選的切換,實現半雙工通話效果,但現在市面上都是全雙工...
    程式設計 發佈於2024-11-05
  • 逐步建立網頁:探索 HTML 中的結構和元素
    逐步建立網頁:探索 HTML 中的結構和元素
    ?今天標誌著我軟體開發之旅的關鍵一步! ?我編寫了第一行程式碼,深入研究了 HTML 的本質。涵蓋的元素和標籤。昨天,我探索了建立網站的拳擊技術,今天我透過創建頁眉、頁腳和內容區域等部分將其付諸實踐。我還添加了各種 HTML 元素,包括圖像元素和連結元素,甚至嘗試在單頁網站上進行內部連結。看到這些部...
    程式設計 發佈於2024-11-05
  • 專案創意不一定是獨特的:原因如下
    專案創意不一定是獨特的:原因如下
    在創新領域,存在一個常見的誤解,即專案創意需要具有開創性或完全獨特才有價值。然而,事實並非如此。我們今天使用的許多成功產品與其競爭對手共享一組核心功能。讓他們與眾不同的不一定是想法,而是他們如何執行它、適應用戶需求以及在關鍵領域進行創新。 通訊應用案例:相似但不同 讓我們考慮一下 ...
    程式設計 發佈於2024-11-05
  • HackTheBox - Writeup 社論 [已退休]
    HackTheBox - Writeup 社論 [已退休]
    Neste writeup iremos explorar uma máquina easy linux chamada Editorial. Esta máquina explora as seguintes vulnerabilidades e técnicas de exploração: S...
    程式設計 發佈於2024-11-05

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3