Группировка элементов массива, но ключ Array - PullRequest
2 голосов
/ 04 апреля 2020

Сгруппируйте элемент Array по одному из его свойств. Проблема в том, что это свойство является массивом.

Правила: все элементы в этом свойстве должны быть одинаковыми, чтобы сделать его одной группой.

Образец массива:

 [{name:'classOne',id:"c1",student:[{name:'student1',id:"student1"},{name:'student2',id:"student2"}]},
 {name:'classTwo',id:"c2",student:[{name:'student1',id:"student1"}]},
{name:'classThree',id:"c3",student:[{name:'student3',id:"student3"}]},
{name:'classFour',id:"c4",student:[{name:'student1',id:"student1"},{name:'student2',id:"student2"}]},
{name:'classFive',id:"c4",student:[{name:'student1',id:"student1"},{name:'student2',id:"student2"},{name:'student3',id:"student3"}]}
]

Ожидаемый результат:

{
    key1:[
        {name:'classOne',id:"c1",student:[{name:'student1',id:"student1"},{name:'student2',id:"student2"}]
        {name:'classFour',id:"c4",student:[{name:'student1',id:"student1"},{name:'student2',id:"student2"}]
    ],
    key2:[
        {name:'classTwo',id:"c2",student:[{name:'student1',id:"student1"}]},
    ],
    key3:[
        {name:'classThree',id:"c3",student:[{name:'student3',id:"student3"}]},
    ],
    key4:[
        {name:'classFive',id:"c4",student:[{name:'student1',id:"student1"},{name:'student2',id:"student2"},{name:'student3',id:"student3"}]}
    ]
}

Мой пример функции

export function groupByArrayKey<T>(key: string, arrayValue: T[]) {
    let result = {};
    return arrayValue.reduce((result, currentVal) => {
        const currentArray = getDeepValue(currentVal, key);
        const resultKey = currentArray[0].id;
        const keyWithLen = resultKey + currentArray.length;
        if (resultKey in result) {
            const resultArray = getDeepValue(result[resultKey][0], key);
            const isEql = isEqual(resultArray, currentArray);
            if (isEql) {
                (result[resultKey] = result[resultKey] || []).push(currentVal);
            } else {
                (result[keyWithLen] = result[keyWithLen] || []).push(currentVal);
            }
        } else if (keyWithLen in result) {
            const resultArray = getDeepValue(result[keyWithLen][0], key);
            const isEql = isEqual(resultArray, currentArray);
            if (isEql) {
                delete result[keyWithLen];
                (result[resultKey] = result[resultKey] || []).push(resultArray, currentVal);
            } else {
                const dummyKey = Math.random();
                (result[dummyKey] = result[dummyKey] || []).push(currentVal);
            }
        } else {
            console.log('third');

            (result[resultKey] = result[resultKey] || []).push(currentVal);
        }
        return result;
    }, {});
}

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

GroupBy: Student

Работает нижеследующая функция, но есть ли другие, чтобы написать это, в компактном виде?

1 Ответ

0 голосов
/ 04 апреля 2020

Один из вариантов - создать объект со свойствами строковых student s. На каждой итерации ввода вводите в список студентов, чтобы найти ключ для поиска. Если ключ не существует для объекта, создайте там массив. Затем pu sh в массив.

Например, входной объект { name: 'name', student: ['a', 'b'] } в качестве первого элемента во входном массиве приведет к тому, что объект будет выглядеть следующим образом на первой итерации:

{
  '["a","b"]': [{ name: 'name', student: ['a', 'b'] }]
}

В конце взять значения объекта:

const input = [
  {name:'classOne',id:"c1",student:[{name:'student1',id:"student1"},{name:'student2',id:"student2"}]},
  {name:'classTwo',id:"c2",student:[{name:'student1',id:"student1"}]},
  {name:'classThree',id:"c3",student:[{name:'student3',id:"student3"}]},
  {name:'classFour',id:"c4",student:[{name:'student1',id:"student1"},{name:'student2',id:"student2"}]},
  {name:'classFive',id:"c4",student:[{name:'student1',id:"student1"},{name:'student2',id:"student2"},{name:'student3',id:"student3"}]}
];

const groupByArrayKey = (key, inputArr) => {
  const outputArraysByStringifiedValue = {};
  for (const item of inputArr) {
    const key = JSON.stringify(item.student);
    if (!outputArraysByStringifiedValue[key]) outputArraysByStringifiedValue[key] = [];
    outputArraysByStringifiedValue[key].push(item);
  }
  return Object.values(outputArraysByStringifiedValue);
}

console.log(groupByArrayKey('student', input));
...