Пост

Группировка объектов в javascript

Способы как можно сгруппировать массив объектов по ключу

Группировка объектов в javascript

Группировка объектов в массиве не такая уже и тривиальная задача, но все же ее можно решить несколькими способами.

Способ 1

Первое, что приходит в голову при решении данной задачи, использование функции reduce.

Допустим есть массив объектов нужно сгруппировать их определенному ключу.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// Массив пользователей
const users = [
    {name : "Test", role: "group1"},
    {name : "Test1", role: "group1"},
    {name : "Test2", role: "group2"},
    {name : "Test3", role: "group1"},
    {name : "Test4", role: "group3"},
    {name : "Test5", role: "group2"},
    {name : "Test6", role: "group1"}
];

const groupping = users.reduce( (acc, person) => {
    // Если в аккумуляторе нет ключа, то формируем его и делаем пустой массив
    if (!acc[person.role]) {
        acc[person.role] = [];
    }
    // Наполняем массив значениями
    acc[person.role].push(person.name);
    // Возвращаем аккумулятор
    return acc;
}, {});

// Корректный результат
/*
 {
  "group1": [
    "Test",
    "Test1",
    "Test3",
    "Test6"
  ],
  "group2": [
    "Test2",
    "Test5"
  ],
  "group3": [
    "Test4"
  ]
} 
 */

Так, а если нам нужны не массивы значений, а объекты, перепишем и подсократим решение.

Кода получилось меньше

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
const grouping = users.reduce((result, item) => {
    // Процесс начинается с пустого объекта
    // Создаем ключи, если нет то пустой массив, и в итоге заполняем массив текущим объектом
    (result[item.role] = result[item.role] || []).push(item);
    return result;
}, {});


/*
{
  "group1": [
    {
      "name": "Test",
      "role": "group1"
    },
    {
      "name": "Test1",
      "role": "group1"
    },
    {
      "name": "Test3",
      "role": "group1"
    },
    {
      "name": "Test6",
      "role": "group1"
    }
  ],
  "group2": [
    {
      "name": "Test2",
      "role": "group2"
    },
    {
      "name": "Test5",
      "role": "group2"
    }
  ],
  "group3": [
    {
      "name": "Test4",
      "role": "group3"
    }
  ]
}
 */

Способ 2

Еще один способ группировки элементов, использовать Map.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
// Массив слушателей
const users = [
    {name : "Test", role: "group1"},
    {name : "Test1", role: "group1"},
    {name : "Test2", role: "group2"},
    {name : "Test3", role: "group1"},
    {name : "Test4", role: "group3"},
    {name : "Test5", role: "group2"},
    {name : "Test6", role: "group1"}
];

const grouped = new Map();

users.forEach(item => {
    if (!grouped.has(item.role)) {
        grouped.set(item.role, []);
    }
    grouped.get(item.role).push(item);
});

const grouping = Object.fromEntries(grouped);

/*
{
  "group1": [
    {
      "name": "Test",
      "role": "group1"
    },
    {
      "name": "Test1",
      "role": "group1"
    },
    {
      "name": "Test3",
      "role": "group1"
    },
    {
      "name": "Test6",
      "role": "group1"
    }
  ],
  "group2": [
    {
      "name": "Test2",
      "role": "group2"
    },
    {
      "name": "Test5",
      "role": "group2"
    }
  ],
  "group3": [
    {
      "name": "Test4",
      "role": "group3"
    }
  ]
}
 */

Способ 3

Группировка по нескольким полям. Если есть необходимость группировки по нескольким полям, можно использовать reduce для этого.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// Массив слушателей
const users = [
    {name : "Test", role: "group1", group: "1"},
    {name : "Test1", role: "group1", group: "2"},
    {name : "Test2", role: "group2", group: "1"},
    {name : "Test3", role: "group1", group: "3"},
    {name : "Test4", role: "group3", group: "1"},
    {name : "Test5", role: "group2", group: "2"},
    {name : "Test6", role: "group1", group: "1"}
];

const groupped = users.reduce((result, item) => {
    const key = `${item.role}-${item.group}`;
    (result[key] = result[key] || []).push(item);
    return result;
}, {});

/*
{
  "group1-1": [
    {
      "name": "Test",
      "role": "group1",
      "group": "1"
    },
    {
      "name": "Test6",
      "role": "group1",
      "group": "1"
    }
  ],
  "group1-2": [
    {
      "name": "Test1",
      "role": "group1",
      "group": "2"
    }
  ],
  "group2-1": [
    {
      "name": "Test2",
      "role": "group2",
      "group": "1"
    }
  ],
  "group1-3": [
    {
      "name": "Test3",
      "role": "group1",
      "group": "3"
    }
  ],
  "group3-1": [
    {
      "name": "Test4",
      "role": "group3",
      "group": "1"
    }
  ],
  "group2-2": [
    {
      "name": "Test5",
      "role": "group2",
      "group": "2"
    }
  ]
}
 */
Авторский пост защищен лицензией CC BY 4.0 .

Хотите оптимизировать свой бизнес, нужен сервис, сайт или интеграция.

Бесплатно расчитаю время разработки, предложу решение вашей задачи.