原始JSON数据(平台):
[
{"id":"1","first_name":"Jason","last_name":"Martin","start_date":"1996-07-25","end_date":"2006-07-25","salary":"1234.56","city":"Toronto","description":"Programmer","department":"Finance","active":"1"},
{"id":"2","first_name":"Alison","last_name":"Mathews","start_date":"1976-03-21","end_date":"1986-02-21","salary":"6661.78","city":"Vancouver","description":"Tester","department":"Finance","active":"1"},
{"id":"3","first_name":"James","last_name":"Smith","start_date":"1978-12-12","end_date":"1990-03-15","salary":"6544.78","city":"Vancouver","description":"Tester","department":"QA","active":"1"},
{"id":"4","first_name":"Celia","last_name":"Rice","start_date":"1982-10-24","end_date":"1999-04-21","salary":"2344.78","city":"Vancouver","description":"Manager","department":"HR","active":"1"},
{"id":"5","first_name":"Robert","last_name":"Black","start_date":"1984-01-15","end_date":"1998-08-08","salary":"2334.78","city":"Vancouver","description":"Tester","department":"IT","active":"1"},
{"id":"6","first_name":"Linda","last_name":"Green","start_date":"1987-07-30","end_date":"1996-01-04","salary":"4322.78","city":"New York","description":"Tester","department":"QA","active":"1"},
{"id":"7","first_name":"David","last_name":"Larry","start_date":"1990-12-31","end_date":"1998-02-12","salary":"7897.78","city":"New York","description":"Manager","department":"HR","active":"1"}
]
我需要调用这样的函数:
nest(data,["city","description","department"])
第一个参数是整个数据集,第二个参数是定义嵌套级别的列数组。
预期的JSON输出:
[
{key: "city", value: "Toronto", count: 1, children:
[
{key: "description", value: "Programmer", count: 1, children:
[
{key: "department", value: "Finance", count: 1}
]
}
]
},
{key: "city", value: "Vancouver", count: 2, children:
[
{key: "description", value: "Tester", count: 3, children:
[
{key: "department", value: "Finance", count: 1},
{key: "department", value: "QA", count: 1},
{key: "department", value: "IT", count: 1}
]
},
{key: "description", value: "Manager", count: 1}
]
},
{key: "city", value: "New York", count: 2, children:
[
{key: "description", value: "Tester", count: 1, children:
[
{key: "department", value: "QA", count: 1}
]
},
{key: "description", value: "Manager", count: 1, children:
[
{key: "department", value: "HR", count: 1}
]
}
]
}
我尝试编写一些递归函数,但是当我必须动态搜索树以避免重复时,它会一直卡住。
答案 0 :(得分:10)
认为这是一个有趣的小问题,所以我做到了......但是,我确实同意那些问“你到目前为止尝试了什么”的人。通常,您应该讨论特定的问题。
// Groups a flat array into a tree.
// "data" is the flat array.
// "keys" is an array of properties to group on.
function groupBy(data, keys) {
if (keys.length == 0) return data;
// The current key to perform the grouping on:
var key = keys[0];
// Loop through the data and construct buckets for
// all of the unique keys:
var groups = {};
for (var i = 0; i < data.length; i++)
{
var row = data[i];
var groupValue = row[key];
if (groups[groupValue] == undefined)
{
groups[groupValue] = new Array();
}
groups[groupValue].push(row);
}
// Remove the first element from the groups array:
keys.reverse();
keys.pop()
keys.reverse();
// If there are no more keys left, we're done:
if (keys.length == 0) return groups;
// Otherwise, handle further groupings:
for (var group in groups)
{
groups[group] = groupBy(groups[group], keys.slice());
}
return groups;
}
调用这样的方法:
var groupedData = groupBy(data, ["city","description","department"]);
此方法对您的数据的输出如下所示:
{
"Toronto": {
"Programmer": {
"Finance": [
{
"id": "1", "first_name": "Jason", "last_name": "Martin", "start_date": "1996-07-25", "end_date": "2006-07-25", "salary": "1234.56", "city": "Toronto", "description": "Programmer", "department": "Finance", "active": "1"
}
]
}
},
"Vancouver": {
"Tester": {
"Finance": [
{
"id": "2", "first_name": "Alison", "last_name": "Mathews", "start_date": "1976-03-21", "end_date": "1986-02-21", "salary": "6661.78", "city": "Vancouver", "description": "Tester", "department": "Finance", "active": "1"
}
],
"QA": [
{
"id": "3", "first_name": "James", "last_name": "Smith", "start_date": "1978-12-12", "end_date": "1990-03-15", "salary": "6544.78", "city": "Vancouver", "description": "Tester", "department": "QA", "active": "1"
}
],
"IT": [
{
"id": "5", "first_name": "Robert", "last_name": "Black", "start_date": "1984-01-15", "end_date": "1998-08-08", "salary": "2334.78", "city": "Vancouver", "description": "Tester", "department": "IT", "active": "1"
}
]
},
"Manager": {
"HR": [
{
"id": "4", "first_name": "Celia", "last_name": "Rice", "start_date": "1982-10-24", "end_date": "1999-04-21", "salary": "2344.78", "city": "Vancouver", "description": "Manager", "department": "HR", "active": "1"
}
]
}
},
"New York": {
"Tester": {
"QA": [
{
"id": "6", "first_name": "Linda", "last_name": "Green", "start_date": "1987-07-30", "end_date": "1996-01-04", "salary": "4322.78", "city": "New York", "description": "Tester", "department": "QA", "active": "1"
}
]
},
"Manager": {
"HR": [
{
"id": "7", "first_name": "David", "last_name": "Larry", "start_date": "1990-12-31", "end_date": "1998-02-12", "salary": "7897.78", "city": "New York", "description": "Manager", "department": "HR", "active": "1"
}
]
}
}
}
因为这些组都是javascript对象,所以您不需要那个“count”成员。您可以简单地使用数组的.length属性。
使用javascript的for (var group in groups)
语法遍历群组。
答案 1 :(得分:7)
您可以查看D3.js中的nest()
运算符:
https://github.com/mbostock/d3/blob/48ad44fdeef32b518c6271bb99a9aed376c1a1d6/src/arrays/nest.js
这是D3的一部分,一个更大的库,但是快速查看我刚刚链接到的代码,我不认为这有任何依赖关系,所以你应该能够在这里解除代码以便在你自己的项目中使用。用法为described here in the docs - 您链接.key()
方法以定义嵌套结构的每个层的键。在您的情况下,这可能看起来像:
data = d3.nest()
.key(function(d) { return d.city })
.key(function(d) { return d.description })
.entries(data);
这种结构与你所拥有的结构略有不同,但它在功能上非常相似:
[
{
"key": "Toronto",
"values": [
{
"key": "Programmer",
"values": [
{
"active": "1",
"city": "Toronto",
"department": "Finance",
"description": "Programmer",
"end_date": "2006-07-25",
"first_name": "Jason",
"id": "1",
"last_name": "Martin",
"salary": "1234.56",
"start_date": "1996-07-25"
},
// etc ...
]
}
]
},
// etc ...
]
答案 2 :(得分:0)
在@nrabinowitz提供的示例的基础上,这里是使用最初提议的API传递集合的nest函数和一个属性名称数组作为args,使用引擎盖下的d3.nest:
function nest(data, keys) {
var nest = d3.nest();
keys.forEach(function(k) {
nest.key(function(d) {
return d[k];
})
});
return nest.entries(data);
}
答案 3 :(得分:0)
使用https://www.npmjs.com/package/nesthydrationjs
const NestHydrationJS = require('nesthydrationjs')();
function getNestHydrationJS (results) {
return NestHydrationJS.nest(results);
}