厲害了,JavaScript 新提案:array.groupBy()

前端小智發表於2022-01-18
作者:Ashish Lahoti
譯者:前端小智
來源:dmitripavlutin

許多開發人員喜歡 Ruby 程式語言,因為它具有豐富的標準實用程式庫。例如,Ruby中的陣列有大量的方法。

不過,我們的JavaScript也在努力,在字串和陣列方面逐步豐富了它的標準庫。例如,在以前的文章中,介紹新的 array.at() 方法。

今天我們在來看新的陣列組提案(目前處於第三階段),它引入了新方法 array.groupby()array.groupbytomap() 。它們的 polyfills 檔案可以在 core-js 庫中找到。

接著,我們來看下能從中學到些什麼。

1. array.groupBy()

假設我們有一個產品列表,其中每個產品都是一個具有2個屬性的物件: namecategory

const products = [
  { name: 'apples', category: 'fruits' },
  { name: 'oranges', category: 'fruits' },
  { name: 'potatoes', category: 'vegetables' }
];

在上面的示例中,products 是一個產品物件陣列。

現在,對產品列表執行一個簡單的操作,將產品按類別分組。

const groupByCategory = {
  'fruits': [
    { name: 'apples', category: 'fruits' }, 
    { name: 'oranges', category: 'fruits' },
  ],
  'vegetables': [
    { name: 'potatoes', category: 'vegetables' }
  ]
};

如何從 products 陣列中得到一個類似 groupByCategory 的陣列?

通常的方法是使用array.reduce()來實現,如下所示:

const groupByCategory = products.reduce((group, product) => {
  const { category } = product;
  group[category] = group[category] ?? [];
  group[category].push(product);
  return group;
}, {});
console.log(groupByCategory);
// {
//   'fruits': [
//     { name: 'apples', category: 'fruits' }, 
//     { name: 'oranges', category: 'fruits' },
//   ],
//   'vegetables': [
//     { name: 'potatoes', category: 'vegetables' }
//   ]
// }

products.reduce((acc, product) => { ... }) 將產品陣列還原為一個按類別分組的產品物件。

array.reduce()方法有用且強大,但有時它的可讀性並不是最好的。

因為分組資料是常見的事(從SQL中召回groupby ?),陣列組提案引入了兩個有用的方法:array. groupBy()array.groupByToMap()

下面介紹如何使用 array.groupBy() 建立相同的分類分組:

const groupByCategory = products.groupBy(product => {
  return product.category;
});

console.log(groupByCategory); 

// {
//   'fruits': [
//     { name: 'apples', category: 'fruits' }, 
//     { name: 'oranges', category: 'fruits' },
//   ],
//   'vegetables': [
//     { name: 'potatoes', category: 'vegetables' }
//   ]
// }

products.groupBy(product => {...}) 返回一個物件,其中每個屬性的鍵是類別名稱,值是對應類別的產品陣列。

使用 products.groupBy() 分組比使用 product.reduce() 程式碼更少,更容易理解。

array.groupBy(callback) 接受一個回撥函式,該函式被呼叫時有3個引數:當前陣列項、索引和陣列本身。回撥函式應該返回一個字串:你想新增專案的組名。

const groupedObject = array.groupBy((item, index, array) => {
  // ...
  return groupNameAsString;
});

2. array.groupByToMap()

有時你可能想使用 Map 而不是普通物件。 Map 的好處是它可以接受任何資料型別作為鍵,但普通物件只限於字串和 symbol。

恩,如果你想把資料分組到一個Map中,你可以使用 array.groupByToMap() 方法。

array.groupByToMap(callback)的工作方式與 array.groupBy(callback) 完全一樣,只是它將專案分組到 Map 中,而不是一個普通的 JS 物件中。

例如,將產品陣列按類別名稱分組到一個 ap 中,執行方法如下。

const groupByCategory = products.groupByToMap(product => {
  return product.category;
});

console.log(groupByCategory); 

// Map([
//   ['fruits', [
//     { name: 'apples', category: 'fruits' }, 
//     { name: 'oranges', category: 'fruits' },
//   ]],
//   ['vegetables', [
//     { name: 'potatoes', category: 'vegetables' }
//   ]
// ])

3.總結

如果你想輕鬆地對陣列中的項進行分組(類似於SQL中的GROUP BY),那麼歡迎使用新方法array.groupBy()array.groupByToMap()

兩個函式都接受一個回撥函式,該回撥函式應返回必須插入當前項的組的鍵。

array.groupBy()將這些項分組為一個普通的JavaScript物件,而array.groupByToMap()將它們分組為一個 Map 例項。

如果你想馬上使用這些函式,那麼使用 core-js 庫提供的 polyfill。

編輯中可能存在的bug沒法實時知道,事後為了解決這些bug,花了大量的時間進行log 除錯,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug

原文:https://dmitripavlutin.com/ja...

交流

有夢想,有乾貨,微信搜尋 【大遷世界】 關注這個在凌晨還在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收錄,有一線大廠面試完整考點、資料以及我的系列文章。

相關文章