Regroupement de tableaux en JavaScript

La possibilité de combiner des données en groupes permet aux développeurs de calculer des ensembles de données d’ordre supérieur, comme regrouper les employés par service. Cet article couvre Object.groupBy et Map.groupBy en JavaScript.
Le regroupement de tableaux est une tâche que vous avez probablement implémentée en JavaScript. Si vous utilisez SQL, cela revient à faire un GROUP BY
. Étant donné un ensemble de données, nous pouvons composer un ensemble de données de niveau supérieur en plaçant des données similaires dans un groupe et en identifiant chaque groupe par un identifiant donné.
je vais plonger dans le nouveau Regroupement de tableaux fonctions publiées cette année (2024), à savoir, Object.groupBy
et Map.groupBy
.
La prise en charge de TypeScript pour ces API est disponible sur TypeScript 5.4 pour mes fans de TypeScript. Cependant, vous devrez configurer votre tsconfig.json
cibler ESNext
. Lorsqu’ils sont disponibles dans ES2024, vous pouvez définir la cible sur ES2024
ou plus.
Regroupement de tableaux avant 2024
Le regroupement de tableaux en JavaScript n’est pas un concept nouveau. Nous l’avons mis en œuvre de diverses manières dans le passé. Cela pourrait être fait avec un for
ou foreach
boucle, Array.prototype.reduce
ou la groupBy
fonctionner dans soulignement.js ou lodash.
Étant donné une liste d’employés, voici comment nous regrouperions les données en utilisant reduce()
:
interface Employee {
name: string;
department: string;
age: number;
manager?: Employee;
joined: Date
}
const ceo = {
name: "John Doe",
department: "engineering",
age: 47,
joined: new Date("10-04-2020")
}
const cfo = {
name: "Anna Maria",
department: "finance",
age: 45,
joined: new Date("10-05-2020")
}
const employees: Employee[] = [
ceo,
{
name: "Pop Jones Jr.",
department: "finance",
age: 30,
manager: cfo,
joined: new Date("10-04-2021")
},
{
name: "Sarah Clara",
department: "engineering",
age: 32,
manager: ceo,
joined: new Date("10-05-2021")
},
cfo,
{
name: "Funmi Kola",
department: "engineering",
age: 20,
manager: ceo,
joined: new Date("10-05-2022")
},
{
name: "Julius Maria",
department: "sales",
age: 27,
manager: cfo,
joined: new Date("10-05-2022")
}
]
const groupByDepartment = employees.reduce<Record<string, Employee[]>>((acc, employee) => {
const department = employee.department;
if (acc[department] === undefined) {
acc[department] = [];
}
acc[department].push(employee);
return acc;
}, {});
console.log(groupByDepartment);
La sortie pour groupByDepartment
devrait être:
{
"engineering": [
{
"name": "John Doe",
"department": "engineering",
"age": 47,
"joined": "2020-10-03T22:00:00.000Z"
},
{
"name": "Sarah Clara",
"department": "engineering",
"age": 32,
"manager": {
"name": "John Doe",
"department": "engineering",
"age": 47,
"joined": "2020-10-03T22:00:00.000Z"
},
"joined": "2021-10-04T22:00:00.000Z"
},
{
"name": "Funmi Kola",
"department": "engineering",
"age": 20,
"manager": {
"name": "John Doe",
"department": "engineering",
"age": 47,
"joined": "2020-10-03T22:00:00.000Z"
},
"joined": "2022-10-04T22:00:00.000Z"
}
],
"finance": [
{
"name": "Pop Jones Jr.",
"department": "finance",
"age": 30,
"manager": {
"name": "Anna Maria",
"department": "finance",
"age": 45,
"joined": "2020-10-04T22:00:00.000Z"
},
"joined": "2021-10-03T22:00:00.000Z"
},
{
"name": "Anna Maria",
"department": "finance",
"age": 45,
"joined": "2020-10-04T22:00:00.000Z"
}
],
"sales": [
{
"name": "Julius Maria",
"department": "sales",
"age": 27,
"manager": {
"name": "Anna Maria",
"department": "finance",
"age": 45,
"joined": "2020-10-04T22:00:00.000Z"
},
"joined": "2022-10-04T22:00:00.000Z"
}
]
}
Regroupement avec Object.groupBy
Le Object.groupBy
La fonction est utilisée pour regrouper selon une valeur de chaîne donnée. Cela signifie : étant donné un itérable, regroupez ses éléments en fonction de la valeur renvoyée par la fonction de rappel fournie. La valeur renvoyée par le rappel doit être quelque chose qui peut être converti en chaîne ou en symbole.
Object.groupBy
renvoie un objet prototype nul qui a des propriétés distinctes pour chaque groupe, contenant des tableaux avec les éléments du groupe. L’utilisation d’un objet prototype nul permet une déstructuration ergonomique et évite les collisions accidentelles avec les propriétés globales de l’objet.
En utilisant le même ensemble de données, nous pouvons regrouper les employés par service en utilisant Object.groupBy
:
const groupByDepartment = Object.groupBy(employees, ({department}) => department)
Cela nous donne le même résultat que reduce
méthode mais avec moins de code. La sortie pour groupByDepartment
devrait être:
{
"engineering": [
{
"name": "John Doe",
"department": "engineering",
"age": 47,
"joined": "2020-10-03T22:00:00.000Z"
},
{
"name": "Sarah Clara",
"department": "engineering",
"age": 32,
"manager": {
"name": "John Doe",
"department": "engineering",
"age": 47,
"joined": "2020-10-03T22:00:00.000Z"
},
"joined": "2021-10-04T22:00:00.000Z"
},
{
"name": "Funmi Kola",
"department": "engineering",
"age": 20,
"manager": {
"name": "John Doe",
"department": "engineering",
"age": 47,
"joined": "2020-10-03T22:00:00.000Z"
},
"joined": "2022-10-04T22:00:00.000Z"
}
],
"finance": [
{
"name": "Pop Jones Jr.",
"department": "finance",
"age": 30,
"manager": {
"name": "Anna Maria",
"department": "finance",
"age": 45,
"joined": "2020-10-04T22:00:00.000Z"
},
"joined": "2021-10-03T22:00:00.000Z"
},
{
"name": "Anna Maria",
"department": "finance",
"age": 45,
"joined": "2020-10-04T22:00:00.000Z"
}
],
"sales": [
{
"name": "Julius Maria",
"department": "sales",
"age": 27,
"manager": {
"name": "Anna Maria",
"department": "finance",
"age": 45,
"joined": "2020-10-04T22:00:00.000Z"
},
"joined": "2022-10-04T22:00:00.000Z"
}
]
}
Regroupement avec Map.groupBy
Map.groupBy
est similaire à Object.groupBy
, sauf qu’il renvoie une Map et que l’itérable donné peut être regroupé en utilisant n’importe quelle valeur arbitraire. Dans ce cas, l’ensemble de données peut être regroupé à l’aide d’un objet.
En regardant l’ensemble de données, nous avons défini un manager
biens de certains salariés et lui a attribué le ceo
ou cfo
objet. Nous pouvons regrouper les employés selon leur manager
qui ressemblerait à ceci :
const managerWithTeammates = Map.groupBy(employees, ({manager}) => manager)
La sortie pour managerWithTeammates
devrait ressembler à :
Map (3)
{undefined => [{
"name": "John Doe",
"department": "engineering",
"age": 47,
"joined": "2020-10-03T22:00:00.000Z"
}, {
"name": "Anna Maria",
"department": "finance",
"age": 45,
"joined": "2020-10-04T22:00:00.000Z"
}],
{
"name": "Anna Maria",
"department": "finance",
"age": 45,
"joined": "2020-10-04T22:00:00.000Z"
} => [{
"name": "Pop Jones Jr.",
"department": "finance",
"age": 30,
"manager": {
"name": "Anna Maria",
"department": "finance",
"age": 45,
"joined": "2020-10-04T22:00:00.000Z"
},
"joined": "2021-10-03T22:00:00.000Z"
}, {
"name": "Julius Maria",
"department": "sales",
"age": 27,
"manager": {
"name": "Anna Maria",
"department": "finance",
"age": 45,
"joined": "2020-10-04T22:00:00.000Z"
},
"joined": "2022-10-04T22:00:00.000Z"
}],
{
"name": "John Doe",
"department": "engineering",
"age": 47,
"joined": "2020-10-03T22:00:00.000Z"
} => [{
"name": "Sarah Clara",
"department": "engineering",
"age": 32,
"manager": {
"name": "John Doe",
"department": "engineering",
"age": 47,
"joined": "2020-10-03T22:00:00.000Z"
},
"joined": "2021-10-04T22:00:00.000Z"
}, {
"name": "Funmi Kola",
"department": "engineering",
"age": 20,
"manager": {
"name": "John Doe",
"department": "engineering",
"age": 47,
"joined": "2020-10-03T22:00:00.000Z"
},
"joined": "2022-10-04T22:00:00.000Z"
}]}
Avec cet exemple, nous avons trois groupes :
- Le PDG et le CFO qui n’ont pas de manager, avec
undefined
comme clé d’objet Map. - La directrice financière, Anna Maria, qui a deux employés sous ses ordres. Cela utilise le
cfo
objet comme clé d’objet Map. - Le PDG, John Doe, qui a deux employés sous ses ordres. Cela utilise le
ceo
objet comme clé d’objet Map.
Conclusion
N’est-ce pas étonnant les nouvelles API qui arrivent sur JavaScript ? Le Object.groupBy
et Map.groupBy
les fonctions facilitent le regroupement des données dans un tableau ou un itérable, et elles sont plus ergonomiques que les traditionnelles reduce
méthode. Ils réduisent également la taille de votre bundle en ne nécessitant pas de bibliothèque externe comme lodash
ou underscore.js
.
Pour récapituler, utilisez le Map.groupBy
fonctionnent principalement lors du regroupement d’éléments associés à un objet arbitraire, en particulier lorsque cet objet peut changer au fil du temps. Si l’objet est invariant, vous pouvez le représenter à l’aide d’une chaîne et regrouper les éléments avec Object.groupBy()
. Si vous utilisez TypeScript, définissez la cible sur ESNext
(ou ES2024
quand il sera disponible dans le futur).
Vous trouverez un terrain de jeu avec le code utilisé dans ce billet de blog en utilisant ceci lien.
Si vous avez des questions ou des suggestions, n’hésitez pas à laisser un commentaire. Vous pouvez également me joindre au Twitter. Merci d’avoir lu. 😎
Source link