我有一个json对象数组,如下所示。
[
{
"wrappedItem": {
"systemName": "jira",
"domainObject": "issue",
"eventType": "creation"
},
"id": 39,
"enabled": true
},
{
"wrappedItem": {
"systemName": "jira",
"domainObject": "issue",
"eventType": "predeletion"
},
"id": 40,
"enabled": true
},
{
"wrappedItem": {
"systemName": "jira",
"domainObject": "issue",
"eventType": "deletion"
},
"id": 41,
"enabled": true
},
{
"wrappedItem": {
"systemName": "jira",
"domainObject": "issue",
"eventType": "update"
},
"id": 42,
"enabled": true
},
{
"wrappedItem": {
"systemName": "jira",
"domainObject": "recquirement",
"eventType": "new"
},
"id": 43,
"enabled": true
},
{
"wrappedItem": {
"systemName": "jira",
"domainObject": "recquirement",
"eventType": "old"
},
"id": 44,
"enabled": true
},
{
"wrappedItem": {
"systemName": "bitbucket",
"domainObject": "branch",
"eventType": "creation"
},
"id": 45,
"enabled": true
},
{
"wrappedItem": {
"systemName": "bitbucket",
"domainObject": "branch",
"eventType": "deletion"
},
"id": 46,
"enabled": true
},
{
"wrappedItem": {
"systemName": "bitbucket",
"domainObject": "pull-request",
"eventType": "creation"
},
"id": 47,
"enabled": true
}
]
如果您仔细观察上述数据,可以看到数据可以根据systemName
进行分组,然后是domainObject
,然后是eventType
。
我想将数据显示为像时尚一样的树。为此,我决定使用angular-ui-tree第三方库。它期望json对象以某种方式。 (请转到该链接以查看所需的json对象的结构)。
我有一个要求,我必须将我的数据转换为angular-ui-tree
所需的结构,以便我可以将我的数据显示为树。
最终,我期待json对象看起来像:
[
{
"systemName": "jira",
"domains": [
{
"domainObject": "issue",
"eventTypes": [
{
"eventType": "creation",
"id": 39,
"enabled": true
},
{
"eventType": "pre-deletion",
"id": 40,
"enabled": true
},
{
"eventType": "deletion",
"id": 41,
"enabled": true
},
{
"eventType": "issue",
"id": 42,
"enabled": true
}
]
},
{
"domainObject": "requirement",
"eventTypes": [
{
"eventType": "new",
"id": 43,
"enabled": true
},
{
"eventType": "old",
"id": 44,
"enabled": true
}
]
}
]
},
{
"systemName": "bitbucket",
"domains": [
{
"domainObject": "branch",
"eventTypes": [
{
"eventType": "creation",
"id": 45,
"enabled": true
},
{
"eventType": "deletion",
"id": 46,
"enabled": true
}
]
},
{
"domainObject": "pull-request",
"eventTypes": [
{
"eventType": "creation",
"id": 47,
"enabled": true
}
]
}
]
}
]
如您所见,此数据按systemName
分组,然后是domainObject
,后跟eventType
。
有人可以帮我转换上面显示的结构中的数据。
答案 0 :(得分:2)
您可以使用嵌套哈希表并使用给定键对项目进行分组。
基本上,此提案适用于不同长度的分组属性。在这种情况下,它按
分组groups = { 'wrappedItem.systemName': 'domains', 'wrappedItem.domainObject': 'eventTypes' }
然后它需要一个用于构建最终对象的函数
{ eventType: "creation", id: 39, enabled: true }
在嵌套分组的末尾
fn = function (o) { return { eventType: o.wrappedItem.eventType, id: o.id, enabled: o.enabled }; }
函数getGroupedData
需要数据数组,分组对象和回调以生成内部项。
关键功能是一个对象,它为每个级别的组保存一个数组。
一开始,哈希表有一个属性和对结果数组的引用
{ _: result }
在数据数组的第一个循环中,通过迭代所有组,它为每个组获得一个新的级别。
首先,它获取第一个组属性的值,即'jira'
。它用于检查哈希表中是否存在该属性。实际上不存在'jira'
,并且使用与原始哈希表相同的模式生成新对象。
{ _: result jira: { _: [] } }
为结果集生成另一个对象
{ systemName: "jira", domains": [] }
并添加到结果
{ _: [ { systemName: "jira", domains: [] // <---+ } // | domains and jira._ ], // | share the same jira: { // | reference to the array _: [] // <---+ } }
为什么我需要对结果数组有两个不同的引用?
因为您需要一个特殊的结果数据结构。它是面向数组的,但访问是通过索引完成的。另一个结构可以通过属性直接访问,更容易访问,没有更多方法。
对于下一个组,如果在实际对象中是名为jira
的属性,则返回'issue'
的对象并执行另一个检查。这显然是在第一个循环中并非如此并且已添加。实际对象看起来像
{ _: [ { domainObject: "issue", eventTypes: [] } ], issue: { _: [] } }
_[0].eventTypes
和issue._
再次共享对数组的引用。
现在在数据的第一个循环结束时,哈希对象看起来像那样
{ // + same objects _: [ // -+ result set { // | systemName: "jira", // | domains: [ // | { // + | domainObject: "issue", // + | eventTypes: [ // + | { // + + | eventType: "creation", // + + | id: 39, // + + | enabled: true // + + | } // + + | ] // + | } // + | ] // | } // -+ ], // jira: { // _: [ // { // + domainObject: "issue", // + eventTypes: [ // + { // + + eventType: "creation", // + + id: 39, // + + enabled: true // + + } // + + ] // + } // + ], // issue: { // _: [ // { // + eventType: "creation", // + id: 39, // + enabled: true // + } // + ] // } // } // } //
数据数组循环到最后,所有组合现在都在对象中,并且已创建所有分组数组。然后只返回结果集。
function getGroupedData(data, groups, fn) {
var keys = Object.keys(groups),
result = [];
data.forEach(function (a) {
keys.reduce(function (r, k) {
var temp,
value = k.split('.').reduce(function (r, l) {
return (r || {})[l];
}, a);
if (!r[value]) {
r[value] = { _: [] };
temp = {};
temp[k.split('.').pop()] = value;
temp[groups[k]] = r[value]._;
r._.push(temp);
}
return r[value];
}, this)._.push(fn(a));
}, { _: result });
return result;
}
var data = [{ wrappedItem: { systemName: "jira", domainObject: "issue", eventType: "creation" }, "id": 39, enabled: true }, { wrappedItem: { systemName: "jira", domainObject: "issue", eventType: "predeletion" }, "id": 40, enabled: true }, { wrappedItem: { systemName: "jira", domainObject: "issue", eventType: "deletion" }, "id": 41, enabled: true }, { wrappedItem: { systemName: "jira", domainObject: "issue", eventType: "update" }, "id": 42, enabled: true }, { wrappedItem: { systemName: "jira", domainObject: "recquirement", eventType: "new" }, "id": 43, enabled: true }, { wrappedItem: { systemName: "jira", domainObject: "recquirement", eventType: "old" }, "id": 44, enabled: true }, { wrappedItem: { systemName: "bitbucket", domainObject: "branch", eventType: "creation" }, "id": 45, enabled: true }, { wrappedItem: { systemName: "bitbucket", domainObject: "branch", eventType: "deletion" }, "id": 46, enabled: true }, { wrappedItem: { systemName: "bitbucket", domainObject: "pull-request", eventType: "creation" }, "id": 47, enabled: true }],
groups = { 'wrappedItem.systemName': 'domains', 'wrappedItem.domainObject': 'eventTypes' },
fn = function (o) {
return { eventType: o.wrappedItem.eventType, id: o.id, enabled: o.enabled };
};
console.log(getGroupedData(data, groups, fn));
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
答案 1 :(得分:2)
使用<div ng-app="hello">
<div test-case condition="active">Active</div>
<div test-case condition="pending">Pending</div>
<div test-case condition="archived">Archived</div>
<div test-case condition="finished">Finished</div>
</div>
散列对象及其子对象,然后使用reduce
和Object.keys
将这些散列对象转换为如下数组:
map
示例:强>
function group(arr) {
// PHASE 1: wrap the object and the sub-objects into hash objects (group them)
var hash = arr.reduce(function(h, o) { // for each object o in the array arr
var sn = o.wrappedItem.systemName; // get the systemName
var dob = o.wrappedItem.domainObject; // get the domainObject
var ev = {eventType: o.wrappedItem.eventType, id: o.id, enabled: o.enabled}; // create an eventType object
if(h[sn]) { // if the systemName sn is already hashed
if(h[sn].domainHash[dob]) // if the domain object dob is already hashed
h[sn].domainHash[dob].eventTypes.push(ev); // then push the eventType ev into its eventTypes array
else // if not (the domain object is not hashed yet) then create a new domain object that have the eventType ev as the only item in its eventTypes array
h[sn].domainHash[dob] = {domainObject: dob, eventTypes: [ev]};
}
else { // if not (the systemName sn is not hashed yet)
h[sn] = {systemName: sn, domainHash: {}}; // create a new systemName object with its domainHash object initialized with the domain object dob which is also initalized with the eventType ev
h[sn].domainHash[dob] = {domainObject: dob, eventTypes: [ev]};
}
return h;
}, {});
// PHASE 2: unwrap the hash objects
return Object.keys(hash).map(function(o) { // unwrap hash
var domains = Object.keys(hash[o].domainHash).map(function(d) { // unwrap domainHash
return hash[o].domainHash[d];
});
delete hash[o].domainHash; // remove the property domainHash
hash[o].domains = domains; // replace it with the property domains
return hash[o];
});
}
<强>解释强>
在第1阶段之后,我们得到一个这样的对象:
var array = [{"wrappedItem":{"systemName":"jira","domainObject":"issue","eventType":"creation"},"id":39,"enabled":true},{"wrappedItem":{"systemName":"jira","domainObject":"issue","eventType":"predeletion"},"id":40,"enabled":true},{"wrappedItem":{"systemName":"jira","domainObject":"issue","eventType":"deletion"},"id":41,"enabled":true},{"wrappedItem":{"systemName":"jira","domainObject":"issue","eventType":"update"},"id":42,"enabled":true},{"wrappedItem":{"systemName":"jira","domainObject":"recquirement","eventType":"new"},"id":43,"enabled":true},{"wrappedItem":{"systemName":"jira","domainObject":"recquirement","eventType":"old"},"id":44,"enabled":true},{"wrappedItem":{"systemName":"bitbucket","domainObject":"branch","eventType":"creation"},"id":45,"enabled":true},{"wrappedItem":{"systemName":"bitbucket","domainObject":"branch","eventType":"deletion"},"id":46,"enabled":true},{"wrappedItem":{"systemName":"bitbucket","domainObject":"pull-request","eventType":"creation"},"id":47,"enabled":true}];
function group(arr) {
var hash = arr.reduce(function(h, o) {
var sn = o.wrappedItem.systemName;
var dob = o.wrappedItem.domainObject;
var ev = {eventType: o.wrappedItem.eventType, id: o.id, enabled: o.enabled};
if(h[sn]) {
if(h[sn].domainHash[dob])
h[sn].domainHash[dob].eventTypes.push(ev);
else
h[sn].domainHash[dob] = {domainObject: dob, eventTypes: [ev]};
}
else {
h[sn] = {systemName: sn, domainHash: {}};
h[sn].domainHash[dob] = {domainObject: dob, eventTypes: [ev]};
}
return h;
}, {});
return Object.keys(hash).map(function(o) {
var domains = Object.keys(hash[o].domainHash).map(function(d) {
return hash[o].domainHash[d];
});
delete hash[o].domainHash;
hash[o].domains = domains;
return hash[o];
});
}
console.log(group(array));
这不是您想要的输出,散列可以更轻松地对项目进行分组,但输出将是一个对象。因此,为了获得所需的结果(数组),您还需要将哈希对象的子对象映射到数组中。
{
"jira": {
systemName: "jira",
domainHash: {
"issue": {
domainObject: "issue",
eventTypes: [...]
},
"other domain object": {
domainObject: "other domain object",
eventTypes: [...]
},
...
}
},
"other system name": {
systemName: "other system name",
domainHash: {
"something": {
domainObject: "something",
eventTypes: [...]
},
...
}
},
...
}
不仅需要映射的systemName对象,还需要映射domainObject对象(对于每个systemName对象):
var result = {
hash["jira"],
hash["other system name"],
...
];