-2

我正在为 Web 应用程序创建树形图,我需要在其中以指定格式传递数据。我有这个数据

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

预期结果 -

 {
         "name": "jmd",
         "children": [
           {
             "name": "ppp1",
             "children": [{
               "name": "feeder",
               "children": [{
                 "name": "rmu1",
                 "children": [{
                   "name": "IT1",
                   "children": [{
                     "aname": "Asset123"
                   }]
                 }]
               }]
             }],
           }
 }

如何使用 lodash 对多个键进行分组?

4

2 回答 2

1

您的expected resultJSON 似乎已损坏。我推断您希望最终得到一个由原始对象的嵌套键构建的对象数组。您可以通过使用递归来实现这一点,并且不需要 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通过嵌套以下道具创建一个新对象,直到没有更多的键。

于 2019-06-11T13:33:01.043 回答
1

您可以创建一个递归函数 ( 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>

于 2019-06-11T16:03:58.813 回答