我有一个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。
我想像时尚一样把数据显示在树上。为此,我决定使用角用户界面树第三方库。它期望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。有人能帮我转换上面所示的结构中的数据吗?
发布于 2017-02-22 20:53:57
使用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];
});
}示例:
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: [...]
},
...
}
},
...
}这不是您想要的输出,散列使对项进行分组变得更容易,但是输出将是一个对象。因此,要获得所需的结果(数组),您需要将散列对象的子对象映射到数组中。
var result = {
hash["jira"],
hash["other system name"],
...
];不只是需要映射的systemName对象,还需要映射domainObject对象(对于每个systemName对象):
var domains = [
domainHash["issue"],
domainHash["other domain object"],
...
];发布于 2017-02-22 20:49:29
您可以使用嵌套哈希表,并使用给定的键对项进行分组。
基本上,这个建议适用于不同长度的分组属性。在这种情况下,它按
组={ 'wrappedItem.systemName':‘域’,'wrappedItem.domainObject':'eventTypes‘}
然后,它需要一个函数来构建最终的对象。
{ eventType:"creation",id: 39,已启用: true }
在嵌套分组的末尾
fn =函数(o) {返回{ eventType: o.wrappedItem.eventType,id: o.id,enabled: o.enabled };}
函数getGroupedData需要一个数据数组、一个分组对象和一个回调来生成内部项。
关键功能是一个对象,它为每个级别的组保存一个数组。
开始时,哈希表有一个属性和对结果数组的引用。
{ _:结果}
在数据数组的第一个循环中,通过迭代所有组,它为每个组获得了一个新的级别。
首先,它获得第一个组属性的值,即'jira'。它用作检查哈希表中是否存在该属性。实际上,'jira'并不存在,并且生成的新对象与原始哈希表的模式相同。
{ _:结果jira:{ _:[] }
并为结果集生成另一个对象。
{ systemName:"jira",域“:[] ]
并添加到结果中
{ _:[{ systemName:"jira",域:[] /<共享同一个jira:{ // _:[] // <-}
为什么我需要对结果数组的两个不同的引用?
因为结果需要特殊的数据结构。它是面向数组的,但是访问是通过索引完成的。另一种结构由属性直接访问,无需更多的方法就更容易访问。
对于下一个组,如果在实际对象中是一个名为jira的属性,则返回'issue'对象并执行另一个检查。这显然是在第一个循环中,而不是情况和添加。实际的对象看起来像
{ _:[{ domainObject:“问题”,eventTypes:[] },问题:{ _:[ ] }
_[0].eventTypes和issue._再次共享对数组的相同引用。
现在,在数据的第一个循环的末尾,散列对象如下所示
{ // +相同的对象_:[ // -+结果集{ // -+ systemName:"jira",// \x_/+ eventTypes: /+{ // ++ eventType:"creation",// ++/ id: 39,// ++启用: true /+颇具} // ++x // +/+\/ -+ ],// jira:{ // _:[ // { // +]domainObject:“问题”,// + eventTypes: // +{ // ++ eventType:“创建”,// ++ id: 39,启用// ++:true // ++} // ++ // +}// + ],//发行:{ // _:// { // + eventType:“创建”,/+ id: 39,// +已启用: 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));.as-console-wrapper { max-height: 100% !important; top: 0; }
https://stackoverflow.com/questions/42401473
复制相似问题