Задать вопрос
Martovitskiy
@Martovitskiy

Как сделать множественную группировку массива на JS?

Всем привет. Группировку на беке без проблем, но как сделать группировку объектов в массиве на js?

Нужно: сначала сгруппировать по order, потом по user_id, потом по stream_id и потом по currency_id
let arr = [
    {
        "order": 1151,
        "stream_id": "256",        
        "currency_id": 1,
        "language_id": 2,
        "balance": 0,
        "user_id": 66,
        "avatar_image": ""
    },
    {
        "order": 1151,
        "stream_id": "188",        
        "currency_id": 1,
        "language_id": 2,
        "balance": 0,
        "user_id": 58,
        "avatar_image": ""
    },
    {
        "order": 1151,
        "stream_id": "256",        
        "currency_id": 1,
        "language_id": 2,
        "balance": 840,
        "user_id": 58,
        "avatar_image": ""
    },
    {
        "order": 1152,
        "stream_id": "214",       
        "currency_id": 1,
        "language_id": 2,
        "balance": 256,
        "user_id": 62,
        "avatar_image": ""
    },
    {
        "order": 1021,
        "stream_id": "214",        
        "currency_id": 1,
        "language_id": 2,
        "balance": 0,
        "user_id": 66,
        "avatar_image": ""
    }
]

arr.map((n, i) => ({ ...n, id: i + 1 }));

const grouped = arr.reduce((acc, n) => {
  const g = n.order || n.stream_id;
  (acc[g] = acc[g] || []).push(n);
  return acc;
}, {});

Как дальше?
  • Вопрос задан
  • 397 просмотров
Подписаться 1 Простой 4 комментария
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
const group = (arr, ...keys) =>
  arr.reduce(((key, acc, n) => (
    (keys.reduce((obj, k) => obj[n[k]] ??= {}, acc)[n[key]] ??= []).push(n),
    acc
  )).bind(null, keys.pop()), {});


const grouped = group(arr, 'order', 'user_id', 'stream_id', 'currency_id');

или

function group(data, keys) {
  const result = {};

  for (const n of data) {
    const objKeys = [].concat(keys(n));
    const arrKey = objKeys.pop();
    (objKeys.reduce((obj, k) => obj[k] ??= {}, result)[arrKey] ??= []).push(n);
  }

  return result;
}


// ваш случай
group(arr, n => [ n.order, n.user_id, n.stream_id, n.currency_id ])

// а вообще, группировать можно не только массивы; количество признаков группировки
// может отличаться для различных элементов; сами признаки и имена групп не обязаны совпадать
// с какими-либо свойствами элементов, а могут являться производными от них значениями
group('12+345-!aщСxE_VЖg', n => {
  const low = n.toLowerCase();
  return (
    low !== n.toUpperCase() ? [ 'буквы', n === low ? 'строчные' : 'заглавные' ] :
    Number.isInteger(+n)    ? [ 'цифры', (n & 1)   ? 'нечётные' :    'чётные' ] :
                              'другое'
  );
})
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы