JavaScript 終於原生支持數組分組了!

来源:https://www.cnblogs.com/cuggz/archive/2023/09/22/17723582.html
-Advertisement-
Play Games

在日常開發中,很多時候需要對數組進行分組,每次都要手寫一個分組函數,或者使用lodash的groupBy函數。好消息是,JavaScript 現在正在引入全新的分組方法:Object.groupBy和Map.groupBy,以後再也不需要手寫分組函數了,目前最新版本的 Chrome(117)已經支持 ...


在日常開發中,很多時候需要對數組進行分組,每次都要手寫一個分組函數,或者使用lodash的groupBy函數。好消息是,JavaScript 現在正在引入全新的分組方法:Object.groupByMap.groupBy,以後再也不需要手寫分組函數了,目前最新版本的 Chrome(117)已經支持了這兩個方法!

以前的數組分組

假設有一個由表示人員的對象組成的數組,需要按照年齡進行分組。可以使用forEach迴圈來實現,代碼如下:

const people = [

  { name: "Alice", age: 28 },

  { name: "Bob", age: 30 },

  { name: "Eve", age: 28 },

];



const peopleByAge = {};



people.forEach((person) => {

  const age = person.age;

  if (!peopleByAge[age]) {

    peopleByAge[age] = [];

  }

  peopleByAge[age].push(person);

});



console.log(peopleByAge);

輸出結果如下:

{

  "28": [{"name":"Alice","age":28}, {"name":"Eve","age":28}],

  "30": [{"name":"Bob","age":30}]

}

也可以使用reduce方法:

const peopleByAge = people.reduce((acc, person) => {

  const age = person.age;

  if (!acc[age]) {

    acc[age] = [];

  }

  acc[age].push(person);

  return acc;

}, {});

無論哪種方式,代碼都略顯繁瑣。每次都要檢查對象,看分組鍵是否存在,如果不存在,則創建一個空數組,並將項目添加到該數組中。

使用 Object.groupBy 分組

可以通過以下方式來使用新的Object.groupBy方法:

const peopleByAge = Object.groupBy(people, (person) => person.age);

可以看到,代碼非常簡潔!

不過需要註意,使用Object.groupBy方法返回一個沒有原型(即沒有繼承任何屬性和方法)的對象。這意味著該對象不會繼承Object.prototype上的任何屬性或方法,例如hasOwnPropertytoString等。雖然這樣做可以避免意外覆蓋Object.prototype上的屬性,但也意味著不能使用一些與對象相關的方法。

const peopleByAge = Object.groupBy(people, (person) => person.age);

console.log(peopleByAge.hasOwnProperty("28"));

// TypeError: peopleByAge.hasOwnProperty is not a function

在調用Object.groupBy時,傳遞給它的回調函數應該返回一個字元串或 Symbol 類型的值。如果回調函數返回其他類型的值,它將被強制轉換為字元串。

在這個例子中,回調函數返回的是一個數字類型的age屬性值,但由於Object.groupBy方法要求鍵必須是字元串或 Symbol 類型,所以該數字會被強制轉換為字元串類型。

console.log(peopleByAge[28]);

// => [{"name":"Alice","age":28}, {"name":"Eve","age":28}]

console.log(peopleByAge["28"]);

// => [{"name":"Alice","age":28}, {"name":"Eve","age":28}]

使用 Map.groupBy 分組

Map.groupByObject.groupBy幾乎做的是相同的事情,只是返回的結果類型不同。Map.groupBy返回一個Map對象,而不是像Object.groupBy返回一個普通的對象。、

const ceo = { name: "Jamie", age: 40, reportsTo: null };

const manager = { name: "Alice", age: 28, reportsTo: ceo };



const people = [

  ceo

  manager,

  { name: "Bob", age: 30, reportsTo: manager },

  { name: "Eve", age: 28, reportsTo: ceo },

];



const peopleByManager = Map.groupBy(people, (person) => person.reportsTo);

這裡根據人的彙報上級將他們進行了分組。如果想通過對象來從這個Map中獲取數據,那麼要求這些對象具有相同的身份或引用。這是因為Map在比較鍵時使用的是嚴格相等(===),只有兩個對象具有相同的引用,才能被認為是相同的鍵。

peopleByManager.get(ceo);

// => [{ name: "Alice", age: 28, reportsTo: ceo }, { name: "Eve", age: 28, reportsTo: ceo }]

peopleByManager.get({ name: "Jamie", age: 40, reportsTo: null });

// => undefined

在上面的例子中,如果嘗試使用與ceo對象類似的對象作為鍵去訪問Map中的項,由於這個對象與之前存儲在Map中的ceo對象不是同一個對象,所以無法檢索到對應的值。

瀏覽器支持

這兩個groupBy方法是 proposal-array-grouping 提案提出的,該提案目前處於第3階段,預計會在 2024 年成為正式標準。

9 月 12 日,Chrome 117發佈,該版本支持了這兩個方法。Firefox Nightly 在一個標誌後已經實現了這兩個方法。Safari已經以不同的名稱實現了這些方法。由於這些方法在 Chrome 中可用,這意味著它們已經在V8中被實現,所以下一次V8更新時它們將在Node中可用。

圖片

圖片

為什麼要使用靜態方法?

你可能會想,為什麼這個功能被實現為Object.groupBy而不是Array.prototype.groupBy。根據提案,有一個庫曾經用不相容的groupBy方法對Array.prototype進行了修改。在考慮為Web新增API時,向後相容性非常重要。幾年前,在嘗試實現Array.prototype.flatten時就出現了一個稱為SmooshGate的事件。

使用靜態方法實際上對未來的可擴展性更好。當RecordsTuples提案實現時,可以添加一個Record.groupBy方法,用於將數組分組為不可變記錄。

簡而言之,使用靜態方法可以更好地保持向後相容性,並提供更好的擴展性,以便在未來添加更多功能和數據結構。

JavaScript 正在填補這些空白,並使我們的開發更簡單。目前,lodash.groupBy每周的 npm 下載量在 150 萬至 200 萬次之間,當所有瀏覽器都支持該方法之後,就不再需要引入lodash.groupBy 庫了!

圖片


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 關於Unity 如何與Blazor Server結合 一、介紹 最近工作中有Unity與Blazor Server結合的需求,在網上找了一圈,發現這方面的資料比較少,特此寫下這篇記錄一下自己的實現過程,希望可以幫到有需要的朋友。(下方多圖預警) OS Version : windows 11 Uni ...
  • 習慣了 linux 命令的快捷操作,使用 winodws 的 shell 感覺效率非常低下,於是開始搜尋工具支持。 剛開始搜到的是 GnuWin32,但是它已經停止更新維護了,於是找到了 Cygwin。當然 Cygwin 還有其他功能,在此不做贅述 下載安裝 1. 登錄 Cygwin官網下載界面,進 ...
  • 1、首先你需要提前準備好jar包或者war包,並想辦法放入Linux環境(或虛擬機)中; 2、java項目的部署需要用到Tomcat或者Jetty,docker可以直接拉取他倆的鏡像,這裡以Tomcat為例: # : 後面需要加上war或者jar對應的Tomcat版本,最好加上, # 否則預設最新的 ...
  • 一、文檔的查看指令 1、tail指令 作用:查看一個文件的末n行 語法:#tail -n 文件的路徑 說明:-n可以不寫,不寫,預設表示10行。 案例:新建一個1.txt文檔,使用tail指令查看root/1.txt文件的末5行和末10行 tail -5 /root/1.txt tail /root ...
  • 1. 線上備份 2. 離線備份 2.1. 關閉MySQL做備份是最簡單、最安全的 2.2. 所有獲取一致性副本的方法中最好的 2.3. 損壞或不一致的風險最小 2.4. 根本不用關心InnoDB緩衝池中的臟頁或其他緩存 2.5. 不需要擔心數據在嘗試備份的過程中被修改 2.5.1. 伺服器不對應用提 ...
  • MySQL 主從複製與讀寫分離 1、什麼是讀寫分離? 讀寫分離,基本的原理是讓主資料庫處理事務性增、改、刪操作(INSERT、UPDATE、DELETE),而從資料庫處理SELECT查詢操作。資料庫複製被用來把事務性操作導致的變更同步到集群中的從資料庫。 2、為什麼要讀寫分離呢? 因為資料庫的“寫” ...
  • 最近,某白酒品牌頻頻吸引大眾眼球,白酒與咖啡、巧克力等聯名衍生品一經推出便掀起熱潮。某商品由於太過火爆,甚至一度售罄下架。 不得不說,我國擁有超大規模內需市場,消費潛力巨大。 當前,創新消費場景加上數字化融合轉型,成為酒企品牌開疆擴土、逆勢增長的重要途徑。 如今越來越多的酒企開始擁抱數字化,建立涵蓋 ...
  • 1. 每個人都知道需要備份,但並不是每個人都能意識到需要的是可恢復的備份 1.1. 如果你沒有提前做好備份規劃,也許以後會發現已經錯失了一些最佳的選擇 1.2. 在伺服器已經配置好以後,才想起應該使用LVM,以便獲取文件系統的快照——但這時已經太遲了 1.3. 如果你沒有計劃做定期的恢復演練,當真的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...