Как сделать форматирование данных с помощью lodash - PullRequest
0 голосов
/ 11 июня 2019

Я создаю древовидную диаграмму для веб-приложения, где мне нужно передать данные в указанном формате. У меня есть эти данные

let arr = [
  {
    "name": "jmd",
    "aname": "Asset123",
    "transformer_name": "IT1",
    "RMU": "rmu1",
    "feeder_name": "feeder",
    "pooling_station": "ppp1",
    "grid_name": "gggg1"
  },
  {
    "name": "jmd",
    "aname": "inv11",
    "transformer_name": "itr11",
    "RMU": "rmu11",
    "feeder_name": "feeder3",
    "pooling_station": "P2",
    "grid_name": "sri"
  }
]

Я пытался использовать приведенный ниже код

**

var results = _(arr)
  .groupBy('name')
  .reduce(function (array, children, key) {
    array.push({
      text: key,
      children: children
    });
    return array;
  },[]);

**

ожидаемый результат -

 {
         "name": "jmd",
         "children": [
           {
             "name": "ppp1",
             "children": [{
               "name": "feeder",
               "children": [{
                 "name": "rmu1",
                 "children": [{
                   "name": "IT1",
                   "children": [{
                     "aname": "Asset123"
                   }]
                 }]
               }]
             }],
           },
           {
             "name": "P2",
             "children": [{
               "name": "feeder3",
               "children": [{
                 "name": "rmu11",
                 "children": [{
                   "name": "itr11",
                   "children": [{
                     "aname": "inv11",
                   }]
                 }]
               }]
             }]
           }
         ]
       }

Используя приведенный выше код, я получаю этот результат -

[{
    "text": "gggg1",
    "children": [{
        "name": "jmd",
        "aname": "Asset123",
        "transformer_name": "IT1",
        "RMU": "rmu1",
        "feeder_name": "feeder",
        "pooling_station": "ppp1",
        "grid_name": "gggg1"
    }]
}, {
    "text": "sri",
    "children": [{
        "name": "jmd",
        "aname": "inv11",
        "transformer_name": "itr11",
        "RMU": "rmu11",
        "feeder_name": "feeder3",
        "pooling_station": "P2",
        "grid_name": "sri"
    }]
}]

Как сгруппировать несколько клавиш с помощью lodash?

Ответы [ 2 ]

1 голос
/ 11 июня 2019

Вы можете создать рекурсивную функцию (recursiveGroupBy), которая получает массив ключей в порядке, который вы хотите сгруппировать.

Для каждой клавиши, кроме последней, функция использует _.groupBy() включ, а затем сопоставляет все группы с объектами с именем (имя группы) и дочерних.Дочерние элементы генерируются путем вызова функции recursiveGroupBy и передачи ей остальных ключей и текущей группы.

Для последнего ключа мы сопоставляем массив и используем _.pick() для создания объекта споследний ключ и его значение.

const { groupBy, map, pick } = _

const recursiveGroupBy = ([key, ...restKeys], arr) => {  
  if(!restKeys.length) { // if last key
    return map(arr, o => pick(o, key)); // convert to an array of objects with the last key and values
  }
  
  const groups = groupBy(arr, key) // group by the current key

  return map(groups, (group, name) => ({ // generate the children's objects
    name,
    children: recursiveGroupBy(restKeys, group)
  }))
}

const arr = [{"name":"jmd","aname":"Asset123","transformer_name":"IT1","RMU":"rmu1","feeder_name":"feeder","pooling_station":"ppp1","grid_name":"gggg1"},{"name":"jmd","aname":"inv11","transformer_name":"itr11","RMU":"rmu11","feeder_name":"feeder3","pooling_station":"P2","grid_name":"sri"}]

const result = recursiveGroupBy(['name', 'pooling_station', 'feeder_name', 'RMU', 'transformer_name', 'aname'], arr)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
1 голос
/ 11 июня 2019

Ваш expected result JSON поврежден. Я сделал вывод, что вы хотите получить массив объектов, созданный из ключей вложенности исходного объекта. Вы можете достичь этого с помощью рекурсии, и lodash не требуется:

const arr = [{
    "name": "jmd",
    "aname": "Asset123",
    "transformer_name": "IT1",
    "RMU": "rmu1",
    "feeder_name": "feeder",
    "pooling_station": "ppp1",
    "grid_name": "gggg1"
  },
  {
    "name": "jmd",
    "aname": "inv11",
    "transformer_name": "itr11",
    "RMU": "rmu11",
    "feeder_name": "feeder3",
    "pooling_station": "P2",
    "grid_name": "sri"
  }
];


const treeView = (arr, groupBy) => {
  return arr.map((el) => buildTree(
    el,
    groupBy ? [...groupBy] : Object.keys(el), // you can pass 'multiple grouping order' as an argument or it will group by all keys
    {}
  ));
}

const buildTree = (obj, keys, state) => {
  if (keys.length === 0) {
    return state;
  }
  state.name = obj[keys.shift()];
  return keys.length === 0 ? state : { ...state,
    children: [buildTree(obj, keys, state)]
  };
}

console.log(treeView(arr, ["name", "pooling_station", "feeder_name", "RMU", "transformer_name", "aname"]));
Функция

treeView отображает рекурсивный buildTree для каждого из своих объектов. buildTree создает новый объект путем вложения следующих реквизитов до тех пор, пока не останется больше ключей.

...