2016-07-14 96 views
1

我有以下來自服務器的示例JSON。重複的對象在內部被id引用(參見下面的JSON)。在JSON中解析引用:Javascript/JSON

[ 
    { "id": 1, 
    "agent": { 
     "id": 1, 
     "firstName": "gghg", 
     "lastName": "gh", 
     "phone": "4543534", 
     "admin": true 
    }, 
    "user":"[email protected]" 
    }, 
    { "id": 2, 
    "agent": 1, // here I want the full object and not the Id 
    "user":"[email protected]" 
    } 
] 

問: 如何解決中給出隨機JSON對象這種方式引用的對象?

(例如,對於上面的示例JSON,我將具有以下輸出:)

[ 
    { "id": 1, 
    "agent": { 
     "id": 1, 
     "firstName": "gghg", 
     "lastName": "gh", 
     "phone": "4543534", 
     "admin": true 
    }, 
    "user":"[email protected]" 
    }, 
    { "id": 2, 
    "agent": { 
     "id": 1, 
     "firstName": "gghg", 
     "lastName": "gh", 
     "phone": "4543534", 
     "admin": true 
    }, 
    "user":"[email protected]" 
    } 
] 
+0

所以你想從服務器得到它後修改JSON或你想在接收到接收JSON在您需要的形式? –

+0

必須從服務器得到它後修改json – kukkuz

回答

2

基本上單個環路提議,收集未解決的鏈路,並且如果發現了它與對象替換所述開口部分中。

var data = [{ "id": 1, "agent": { "id": 1, "firstName": "gghg", "lastName": "gh", "phone": "4543534", "admin": true }, "user": "[email protected]" }, { "id": 2, "agent": 1, "user": "[email protected]" }]; 
 

 
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);

編輯,更寬泛的版本未知屬性引用。

var data = [ 
 
     { id: 1, agent: { id: 1, firstName: "gghg", lastName: "gh", phone: "4543534", admin: true }, user: "[email protected]", abc: 2 }, 
 
     { id: 2, agent: 1, user: "[email protected]", abc: { id: 2, text: 'blabla' } }, 
 
     { id: 3, agent: { id: 1, firstName: "gghg", lastName: "gh", phone: "4543534", admin: true }, user: "[email protected]" }, 
 
    ]; 
 

 
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);

+0

感謝了很多... :) 我從服務器獲取和JSON我從服務器獲取將有多個對象簡稱就像「代理」對象隨機JSON對象.. 我也想檢測哪些屬性需要處理,以便我不必關心來自服務器的每個響應的屬性名稱......如何處理一般情況? – kukkuz

+0

你可以用這個鍵來設置這個對象,比如'this [key] [a [key]] = ...',這取決於你的規格。 –

+0

我仍然是一個新手,有點困惑如何根據你的建議做到這一點 - 你能爲我寫下來嗎? 請注意,服務器的某些響應將具有多個屬性,如「agent」,「tenant」,「provider」,「admin」,這些屬性將在內部引用,對於任何特定響應,我不知道哪些屬性在內部引用。 – kukkuz

0

我想的唯一方法是通過在陣列運行兩次:

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); 
+0

我想過...我從服務器獲得的JSON會有多個對象,就像「代理」對象 – kukkuz

+0

非常感謝:) – kukkuz

+0

如果它可以幫助你,你可以將我的問題標記爲正確的答案) – steppefox

0

試試這個

var data = [ 
 
    { "id": 1, 
 
    "agent": { 
 
     "id": 1, 
 
     "firstName": "gghg", 
 
     "lastName": "gh", 
 
     "phone": "4543534", 
 
     "admin": true 
 
    }, 
 
    "user":"[email protected]" 
 
    }, 
 
    { "id": 2, 
 
    "agent": 1, // here I want the full object and not the Id 
 
    "user":"[email protected]" 
 
    } 
 
]; 
 
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);

+0

我從隨機獲得的JSON對象服務器和我從服務器獲得的JSON將有多個對象,就像「代理」對象一樣。我如何處理一般情況? – kukkuz

+0

@kukkuz你需要將屬性名稱放在一個變量中,比如'var prop ='agent''並通過執行'obj [prop] = JSON.parse(JSON.stringify(map [obj [prop]])來編輯它。 )' – gurvinder372

+0

是的,謝謝...在一般情況下,我還想檢測哪些屬性需要處理,以便我不必關心來自服務器的每個響應的屬性名稱...... – kukkuz

0
var a = [ { "id": 1, "agent": {"id": 1, "firstName": "gghg", "lastName": "gh", "phone": "4543534", 
         "admin": true}, "user":"[email protected]"}, 
      { "id": 2, "agent": 1, "user":"[email protected]"}]; 

//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); 

check working demo

+0

讓我知道,如果這對你有用! –

0

你可以簡單地定義項的吸氣劑只具有代理ID。

var data = [{ "id": 1, "agent": { "id": 1, "firstName": "gghg", "lastName": "gh", "phone": "4543534", "admin": true }, "user": "[email protected]" }, { "id": 2, "agent": 1, "user": "[email protected]" }]; 
 

 
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);