I have the following sample JSON coming from a server. Duplicate objects are being internally referred to by an id (see the JSON below).
我有来自服务器的以下示例JSON。 ID内部引用了重复的对象(请参阅下面的JSON)。
[
{ "id": 1,
"agent": {
"id": 1,
"firstName": "gghg",
"lastName": "gh",
"phone": "4543534",
"admin": true
},
"user":"agent@gmail.com"
},
{ "id": 2,
"agent": 1, // here I want the full object and not the Id
"user":"agent1@gmail.com"
}
]
Question: How do I resolve the objects referred to in this fashion given a random JSON object?
问题:如何在给定随机JSON对象的情况下解析以此方式引用的对象?
(For instance, for the sample JSON above, I will have the below output:)
(例如,对于上面的示例JSON,我将得到以下输出:)
[
{ "id": 1,
"agent": {
"id": 1,
"firstName": "gghg",
"lastName": "gh",
"phone": "4543534",
"admin": true
},
"user":"agent@gmail.com"
},
{ "id": 2,
"agent": {
"id": 1,
"firstName": "gghg",
"lastName": "gh",
"phone": "4543534",
"admin": true
},
"user":"agent1@gmail.com"
}
]
5 个解决方案
#1
2
Basically a single loop proposal, which collects unresolved links and if found the it replaces the open parts with the object.
基本上是一个单循环提议,它收集未解析的链接,如果找到它,则用对象替换打开的部分。
var data = [{ "id": 1, "agent": { "id": 1, "firstName": "gghg", "lastName": "gh", "phone": "4543534", "admin": true }, "user": "agent@gmail.com" }, { "id": 2, "agent": 1, "user": "agent1@gmail.com" }];
data.forEach(function (a) {
if (typeof a.agent === 'object') {
this[a.agent.id] = this[a.agent.id] || {};
this[a.agent.id].data = a.agent;
this[a.agent.id].update && this[a.agent.id].update.forEach(function (b) {
b.agent = a.agent;
});
return;
}
this[a.agent] = this[a.agent] || {};
if (this[a.agent].data) {
a.agent = this[a.agent].data;
return;
}
this[a.agent].update = this[a.agent].update || [];
this[a.agent].update.push(a);
}, Object.create(null));
console.log(data);
Edit, a more generic version for unknown property references.
编辑,未知属性引用的更通用版本。
var data = [
{ id: 1, agent: { id: 1, firstName: "gghg", lastName: "gh", phone: "4543534", admin: true }, user: "agent@gmail.com", abc: 2 },
{ id: 2, agent: 1, user: "agent1@gmail.com", abc: { id: 2, text: 'blabla' } },
{ id: 3, agent: { id: 1, firstName: "gghg", lastName: "gh", phone: "4543534", admin: true }, user: "agent@gmail.com" },
];
data.forEach(function (a) {
Object.keys(a).forEach(function (k) {
if (typeof a[k] === 'object' && 'id' in a[k]) {
this[a[k].id] = this[a[k].id] || {};
this[a[k].id].data = a[k];
this[a[k].id].update && this[a[k].id].update.forEach(function (b) {
b[k] = a[k];
});
return;
}
this[a[k]] = this[a[k]] || {};
if (this[a[k]].data) {
a[k] = this[a[k]].data;
return;
}
this[a[k]].update = this[a[k]].update || [];
this[a[k]].update.push(a);
}, this);
}, Object.create(null));
console.log(data);
#2
0
try this
var data = [
{ "id": 1,
"agent": {
"id": 1,
"firstName": "gghg",
"lastName": "gh",
"phone": "4543534",
"admin": true
},
"user":"agent@gmail.com"
},
{ "id": 2,
"agent": 1, // here I want the full object and not the Id
"user":"agent1@gmail.com"
}
];
var map = {};
//create a map of items by their id
data.forEach( function(obj){ map[ obj.id ] = obj.agent; } );
//iterate the data array and replace agents by their value if their value is a number.
data = data.map( function(obj){
if ( !isNaN( obj.agent ) )
{
obj.agent = JSON.parse( JSON.stringify( map[ obj.agent ] ) );
}
return obj;
});
console.log( data );
#3
0
I think the only way is to run through the array two times:
我认为唯一的方法是两次运行数组:
UPD:
var arr = [ ... ]; // your list of data
var collectionFields = ['agent', 'someOtherField'];
var collections = {};
// collect all information about agents
for (var i = 0; i < arr.length; i++) {
var item = arr[i];
for (var k = 0; k < collectionFields.length; k++) {
var field = collectionFields[k];
if (typeof collections[field] === 'undefined') {
collections[field] = {};
}
if (typeof item[field] === 'object') {
collections[field][item[field].id] = item[field];
}
}
}
for (var j = 0; j < arr.length; j++) {
for (var k = 0; k < collectionFields.length; k++) {
var field = collectionFields[k];
if (typeof arr[j][field] === 'number') {
arr[j][field] = collections[field][arr[j][field]];
}
}
console.log(arr);
#4
0
var a = [ { "id": 1, "agent": {"id": 1, "firstName": "gghg", "lastName": "gh", "phone": "4543534",
"admin": true}, "user":"agent@gmail.com"},
{ "id": 2, "agent": 1, "user":"agent1@gmail.com"}];
//on = $.parseJSON(a);
console.log(a);
//nsole.log(bson);
var b=[];
var mapID = [];
for(var key in a) {
console.log(a[key].agent);
b[key] = a[key];
if($.isNumeric(a[key].agent)){
var id = a[key].agent;
b[key].agent = a[mapID[id]].agent;
}
mapID[a[key].id] = key;
}
console.log(b);
检查工作演示
#5
0
You can simply define a getter for items which has only the agent ID.
您只需为只有代理ID的项目定义一个getter。
var data = [{ "id": 1, "agent": { "id": 1, "firstName": "gghg", "lastName": "gh", "phone": "4543534", "admin": true }, "user": "agent@gmail.com" }, { "id": 2, "agent": 1, "user": "agent1@gmail.com" }];
console.clear();
data.forEach((hash => d => {
var agent = d.agent;
if (typeof agent === 'number')
Object.defineProperty(d, 'agent', {
get: () => hash[agent]
});
else
hash[agent.id] = agent;
})(Object.create(null)));
console.log(data);
#1
2
Basically a single loop proposal, which collects unresolved links and if found the it replaces the open parts with the object.
基本上是一个单循环提议,它收集未解析的链接,如果找到它,则用对象替换打开的部分。
var data = [{ "id": 1, "agent": { "id": 1, "firstName": "gghg", "lastName": "gh", "phone": "4543534", "admin": true }, "user": "agent@gmail.com" }, { "id": 2, "agent": 1, "user": "agent1@gmail.com" }];
data.forEach(function (a) {
if (typeof a.agent === 'object') {
this[a.agent.id] = this[a.agent.id] || {};
this[a.agent.id].data = a.agent;
this[a.agent.id].update && this[a.agent.id].update.forEach(function (b) {
b.agent = a.agent;
});
return;
}
this[a.agent] = this[a.agent] || {};
if (this[a.agent].data) {
a.agent = this[a.agent].data;
return;
}
this[a.agent].update = this[a.agent].update || [];
this[a.agent].update.push(a);
}, Object.create(null));
console.log(data);
Edit, a more generic version for unknown property references.
编辑,未知属性引用的更通用版本。
var data = [
{ id: 1, agent: { id: 1, firstName: "gghg", lastName: "gh", phone: "4543534", admin: true }, user: "agent@gmail.com", abc: 2 },
{ id: 2, agent: 1, user: "agent1@gmail.com", abc: { id: 2, text: 'blabla' } },
{ id: 3, agent: { id: 1, firstName: "gghg", lastName: "gh", phone: "4543534", admin: true }, user: "agent@gmail.com" },
];
data.forEach(function (a) {
Object.keys(a).forEach(function (k) {
if (typeof a[k] === 'object' && 'id' in a[k]) {
this[a[k].id] = this[a[k].id] || {};
this[a[k].id].data = a[k];
this[a[k].id].update && this[a[k].id].update.forEach(function (b) {
b[k] = a[k];
});
return;
}
this[a[k]] = this[a[k]] || {};
if (this[a[k]].data) {
a[k] = this[a[k]].data;
return;
}
this[a[k]].update = this[a[k]].update || [];
this[a[k]].update.push(a);
}, this);
}, Object.create(null));
console.log(data);
#2
0
try this
var data = [
{ "id": 1,
"agent": {
"id": 1,
"firstName": "gghg",
"lastName": "gh",
"phone": "4543534",
"admin": true
},
"user":"agent@gmail.com"
},
{ "id": 2,
"agent": 1, // here I want the full object and not the Id
"user":"agent1@gmail.com"
}
];
var map = {};
//create a map of items by their id
data.forEach( function(obj){ map[ obj.id ] = obj.agent; } );
//iterate the data array and replace agents by their value if their value is a number.
data = data.map( function(obj){
if ( !isNaN( obj.agent ) )
{
obj.agent = JSON.parse( JSON.stringify( map[ obj.agent ] ) );
}
return obj;
});
console.log( data );
#3
0
I think the only way is to run through the array two times:
我认为唯一的方法是两次运行数组:
UPD:
var arr = [ ... ]; // your list of data
var collectionFields = ['agent', 'someOtherField'];
var collections = {};
// collect all information about agents
for (var i = 0; i < arr.length; i++) {
var item = arr[i];
for (var k = 0; k < collectionFields.length; k++) {
var field = collectionFields[k];
if (typeof collections[field] === 'undefined') {
collections[field] = {};
}
if (typeof item[field] === 'object') {
collections[field][item[field].id] = item[field];
}
}
}
for (var j = 0; j < arr.length; j++) {
for (var k = 0; k < collectionFields.length; k++) {
var field = collectionFields[k];
if (typeof arr[j][field] === 'number') {
arr[j][field] = collections[field][arr[j][field]];
}
}
console.log(arr);
#4
0
var a = [ { "id": 1, "agent": {"id": 1, "firstName": "gghg", "lastName": "gh", "phone": "4543534",
"admin": true}, "user":"agent@gmail.com"},
{ "id": 2, "agent": 1, "user":"agent1@gmail.com"}];
//on = $.parseJSON(a);
console.log(a);
//nsole.log(bson);
var b=[];
var mapID = [];
for(var key in a) {
console.log(a[key].agent);
b[key] = a[key];
if($.isNumeric(a[key].agent)){
var id = a[key].agent;
b[key].agent = a[mapID[id]].agent;
}
mapID[a[key].id] = key;
}
console.log(b);
检查工作演示
#5
0
You can simply define a getter for items which has only the agent ID.
您只需为只有代理ID的项目定义一个getter。
var data = [{ "id": 1, "agent": { "id": 1, "firstName": "gghg", "lastName": "gh", "phone": "4543534", "admin": true }, "user": "agent@gmail.com" }, { "id": 2, "agent": 1, "user": "agent1@gmail.com" }];
console.clear();
data.forEach((hash => d => {
var agent = d.agent;
if (typeof agent === 'number')
Object.defineProperty(d, 'agent', {
get: () => hash[agent]
});
else
hash[agent.id] = agent;
})(Object.create(null)));
console.log(data);