将平面的对象数组转换为嵌套的对象数组
Convert flat array of objects into nested array of objects
原始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}
]
}
]
}
)
我试过写一些递归函数,但当我必须动态搜索树以避免重复时,总是卡住。
认为这是一个有趣的小问题,所以我做了…但是,我确实同意那些问"你迄今为止尝试过什么"的人。通常,您应该谈论一个特定的问题。
// 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)
语法遍历组
你可以看看D3.js中的nest()
操作符:https://github.com/mbostock/d3/blob/48ad44fdeef32b518c6271bb99a9aed376c1a1d6/src/arrays/nest.js这是D3的一部分,一个更大的库,但快速查看我刚刚链接到的代码,我不认为这有任何依赖关系,所以你应该能够在这里解除代码用于你自己的项目。用法在这里的文档中描述-您链接.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 ...
]
以@nrabinowitz提供的示例为基础,下面是嵌套函数,使用最初提出的API,将集合和属性名称数组作为参数传递,使用d3。巢在引擎盖下:
function nest(data, keys) {
var nest = d3.nest();
keys.forEach(function(k) {
nest.key(function(d) {
return d[k];
})
});
return nest.entries(data);
}
使用https://www.npmjs.com/package/nesthydrationjs
const NestHydrationJS = require('nesthydrationjs')();
function getNestHydrationJS (results) {
return NestHydrationJS.nest(results);
}
相关文章:
- 将数组对象传递到struts2中的操作类
- 如何使用jquery返回php-json数组对象
- 从其名称获取javascript数组对象
- 值未与数组对象绑定
- 如何按数组/对象值的倍数过滤对象数组
- 在表中显示数组对象
- 在数组对象中分组
- 将第二个或多个数组推送到数组对象 AngularJS 中
- 重新排列 JavaScript 数组/对象
- 键上的javascript数组对象过滤器
- handontable:在不更改数据数组/对象的情况下隐藏某些列
- 用于跟踪购物车可用性的Javascript数组/对象/哈希表
- 重建有角度的java脚本数组对象
- 对JSON数组对象进行排序
- 连接与数组对象相关的文本:方式和位置
- 哪些浏览器和版本支持将常见的类数组对象直接传递到fn.apply()
- 如何使用Handlebars循环数组对象和模板
- 是否可以引用JS数组/对象中的另一个元素
- Javascript中的名称索引-数组/对象
- 数组长度不等于数组对象