Рекурсивная группировка с неизменным js - PullRequest
0 голосов
/ 31 августа 2018
var list = new List([
  { "col1": "1", "col2": "A", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "1", "col2": "A", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "1", "col2": "A", "col3": "bird", "col4": "dog", "col5": "blue"},
  { "col1": "1", "col2": "B", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "1", "col2": "B", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "1", "col2": "B", "col3": "bird", "col4": "dog", "col5": "blue"},
  { "col1": "1", "col2": "C", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "1", "col2": "C", "col3": "bird", "col4": "dog", "col5": "blue"},
  { "col1": "1", "col2": "C", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "2", "col2": "A", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "2", "col2": "A", "col3": "bird", "col4": "dog", "col5": "blue"},
  { "col1": "2", "col2": "A", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "2", "col2": "B", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "2", "col2": "B", "col3": "bird", "col4": "dog", "col5": "blue"},
  { "col1": "2", "col2": "B", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "2", "col2": "C", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "2", "col2": "C", "col3": "bird", "col4": "dog", "col5": "blue"},
  { "col1": "2", "col2": "C", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "3", "col2": "A", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "3", "col2": "A", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "3", "col2": "A", "col3": "bird", "col4": "dog", "col5": "blue"},
  { "col1": "3", "col2": "B", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "3", "col2": "B", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "3", "col2": "B", "col3": "bird", "col4": "dog", "col5": "blue"},
  { "col1": "3", "col2": "C", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "3", "col2": "C", "col3": "cat", "col4": "dog", "col5": "blue"},
  { "col1": "3", "col2": "C", "col3": "bird", "col4": "dog", "col5": "blue"},
  { "col1": "4", "col2": "A", "col3": "cat", "col4": "dog", "col5": "blue"}
  ]);

let groupedData = list.groupBy(x => x['col1'])
  .map(row => row.groupBy(x => x['col2'])
       .map(row => row.groupBy(x => x['col3']))
   );

Это создаст три уровня группировки по col1, col2, а затем col3.

Как бы я сделал это рекурсивно с любыми n номерами столбцов для группировки и любыми столбцами в любом порядке ([coln, col4, coln-1], например)?

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

Проверенный ответ для рекурсивной группировки на объекте списка immutable.js, представляющем таблицу данных:

recursiveGrouping = (columns, list) => {
    columns.forEach(column => {
        list = this.processIterable(column, list);
    })
    return list;
}

processIterable = (column, iterable) => {
    if(List.isList(iterable)) return iterable.groupBy(row => row[column]);
    else if(Map.isMap(iterable)) return iterable.map(value => this.processIterable(column, value));
    else return iterable;
}

Исходя из моего примера выше, я бы сделал этот вызов с этими методами:

let grouped data = this.recursiveGrouping(['col1', 'col2', 'col3'], list);

Возвращает ту же группу, что и ручной вызов для подгруппы.

0 голосов
/ 31 августа 2018

Одним из способов может быть назначить только первый groupBy вызов groupedData, а затем запустить на нем DFS, каждый раз назначая вызов groupBy каждой ячейке на уровне, на котором вы находитесь. Это изменит внутреннюю структуру исходного groupedData, но я думаю, что ваш код уже делает это.

Что-то вроде (не проверено):

function dfs(row, i, n){
  if (i > n)
    return;

  for (let j=0; j<row.length; j++){
    row[j] = row.groupBy(x => x['col' + i]);
    dfs(row[j], i + 1, n);
  }
}

let n = ???

let groupedData = list.groupBy(x => x['col1']);

for (row of groupedData)
  dfs(row, 2, n);
...