![](/img/trans.png)
[英]How to access different levels of a nested graphql response using JavaScript?
[英]How to access innermost levels of doubly nested arrays/objects using plain Javascript?
我懷疑答案很簡單,但是我搜索了該網站和其他網站,但沒有找到一個。 我有一個雙重嵌套的數據結構,無法弄清楚如何在最內層進行迭代。 我猜想它可能涉及到forEach()或map()方法,但我嘗試過的任何方法都沒有。
背景:我已經簡化了該問題的數據。 數據(粘貼在下面)存儲在包含2個零售商店對象的數組中。 每個商店對象都有一個visits
屬性,其值是一組visit對象。 每次訪問(對象)都由訪問日期標識(假設在日期B最多可以有1次訪問存儲A)。 每個訪問對象都包含一個values
屬性,其值是該訪問時進行的交易(購買或退貨)數組。 在實際的完整數據中,每個商店的每個日期的交易數量變化很大。
我需要幫助的任務:(a)將屬性key
重命名為visitDate
,(b)將屬性values
重命名為transactions
,(c)刪除8個冗余屬性(從storeID
到storeVisitDate
),但保留action
和dollarAmount
屬性,以及(d)將屬性dollarAmount
重命名為dollars
。
非常感激任何的幫助。 謝謝。
[
{
"storeName": "Ye Olde Candy Shoppe",
"address": "1313 Vampire Lane, Cityville NY 99999",
"zipCode": "99999",
"storeSize": "large",
"visits": [
{
"key": "5/3/12",
"values": [
{
"storeID": "53454447",
"storeName": "Ye Olde Candy Shoppe",
"city": "Cityville",
"building": "1313",
"street": "Vampire Lane",
"zipcode": "99999",
"storeSize": "large",
"storeVisitDate": "5/3/12",
"action": "Return",
"dollarAmount": "65.43"
},
{
"storeID": "53454447",
"storeName": "Ye Olde Candy Shoppe",
"city": "Cityville",
"building": "1313",
"street": "Vampire Lane",
"zipcode": "99999",
"storeSize": "large",
"storeVisitDate": "5/3/12",
"action": "Purchase",
"dollarAmount": "12.43"
},
{
"storeID": "53454447",
"storeName": "Ye Olde Candy Shoppe",
"city": "Cityville",
"building": "1313",
"street": "Vampire Lane",
"zipcode": "99999",
"storeSize": "large",
"storeVisitDate": "5/3/12",
"action": "Purchase",
"dollarAmount": "5.43"
}
]
},
{
"key": "12/31/12",
"values": [
{
"storeID": "53454447",
"storeName": "Ye Olde Candy Shoppe",
"city": "Cityville",
"building": "1313",
"street": "Vampire Lane",
"zipcode": "99999",
"storeSize": "large",
"storeVisitDate": "12/31/12",
"action": "Purchase",
"dollarAmount": "2.53"
}
]
},
{
"key": "1/24/13",
"values": [
{
"storeID": "53454447",
"storeName": "Ye Olde Candy Shoppe",
"city": "Cityville",
"building": "1313",
"street": "Vampire Lane",
"zipcode": "99999",
"storeSize": "large",
"storeVisitDate": "1/24/13",
"action": "Return",
"dollarAmount": "2.53"
},
{
"storeID": "53454447",
"storeName": "Ye Olde Candy Shoppe",
"city": "Cityville",
"building": "1313",
"street": "Vampire Lane",
"zipcode": "99999",
"storeSize": "large",
"storeVisitDate": "1/24/13",
"action": "Return",
"dollarAmount": "64.22"
}
]
}
]
},
{
"storeName": "Mike's Bikes",
"address": "2626 Aardvark Circle, Townsville NY 88888",
"zipCode": "88888",
"storeSize": "small",
"visits": [
{
"key": "8/8/14",
"values": [
{
"storeID": "24335234",
"storeName": "Mike's Bikes",
"city": "Townsville",
"building": "2626",
"street": "Aardvark Circle",
"zipcode": "88888",
"storeSize": "small",
"storeVisitDate": "8/8/14",
"action": "Purchase",
"dollarAmount": "443.55"
},
{
"storeID": "24335234",
"storeName": "Mike's Bikes",
"city": "Townsville",
"building": "2626",
"street": "Aardvark Circle",
"zipcode": "88888",
"storeSize": "small",
"storeVisitDate": "8/8/14",
"action": "Purchase",
"dollarAmount": "34"
},
{
"storeID": "24335234",
"storeName": "Mike's Bikes",
"city": "Townsville",
"building": "2626",
"street": "Aardvark Circle",
"zipcode": "88888",
"storeSize": "small",
"storeVisitDate": "8/8/14",
"action": "Purchase",
"dollarAmount": "12.32"
}
]
},
{
"key": "10/3/15",
"values": [
{
"storeID": "24335234",
"storeName": "Mike's Bikes",
"city": "Townsville",
"building": "2626",
"street": "Aardvark Circle",
"zipcode": "88888",
"storeSize": "small",
"storeVisitDate": "10/3/15",
"action": "Purchase",
"dollarAmount": "233.1"
},
{
"storeID": "24335234",
"storeName": "Mike's Bikes",
"city": "Townsville",
"building": "2626",
"street": "Aardvark Circle",
"zipcode": "88888",
"storeSize": "small",
"storeVisitDate": "10/3/15",
"action": "Return",
"dollarAmount": "44.99"
}
]
}
]
}
]
沒錯! 您可以使用.map()完成大部分操作。 新的ES6標准使這一切變得更加容易,並且使用以下功能,您甚至都不會修改任何原始數據!:
array.map(store => {
//return a new object that takes all the store info, then reassigns the visits key in a new object
return Object.assign({}, store, {
//map over visits, and reassign the key key to visitDate
visits: store.visits.map(({ key: visitDate, values }) => {
return {
//return an obj with visit date
visitDate,
// do destructuring again to create objects of action,dollars
transactions: values.map(({ action, dollarAmount: dollars }) => ({ action, dollars }))
};
})
});
});
( 此處是jsFiddle上的工作示例 -只需打開JS控制台即可查看轉換后的數據集)
以下是有關解決方案的幾點說明:
它使用“映射”很多,而不是手動遍歷數組。 我發現它更具可讀性。
// Go over all stores stores.map(function(store) { // In each store, go over all visits. store.visits.map(function(visit) { // In each visit, copy 'key' to 'visitDate' // and 'values' to 'transactions'. // Then delete old names ('key' and 'values'). visit.visitDate = visit.key; visit.transactions = visit.values; delete visit.key; delete visit.values; // For each transaction, replace it with a simple // map with only 'action' and 'dollars'. visit.transactions = visit.transactions.map(function(tx) { return { action: tx.action, dollars: tx.dollarAmount }; }); }); });
請注意,在IE9和更高版本中支持map() 。
要重命名屬性,您可以創建一個具有相同值的新屬性,然后delete
舊屬性。
您可以將其用於所有部分,但是在您的結構上,通過使用map()
創建新的“優化”交易並將其分配給新的transactions
屬性,將b,c,d組合在一起看起來更加巧妙。
// (I put this in a function so the logic can be at the top of the snippet) function fixData(stores) { // loop stores and their visits for (var iStore = 0; iStore < stores.length; iStore++) { var store = stores[iStore]; for (var iVisit = 0; iVisit < store.visits.length; iVisit++) { var visit = store.visits[iVisit]; // (a) rename property key to visitDate // add a new property with the same value then delete the old property visit.visitDate = visit.key; delete visit.key; // (b) rename property values to transactions // add a new property with the same value then delete the old property // (c) delete the 8 redundant properties (from storeID to storeVisitDate) // we could delete keys but quicker to map a new object // (d) rename property dollarAmount to dollars. // just give the new object property a different name visit.transactions = visit.values.map(function(trans) { return { action: trans.action, dollars: trans.dollarAmount } }); delete visit.values; } } console.log(stores); } var stores = [{ "storeName": "Ye Olde Candy Shoppe", "address": "1313 Vampire Lane, Cityville NY 99999", "zipCode": "99999", "storeSize": "large", "visits": [{ "key": "5/3/12", "values": [{ "storeID": "53454447", "storeName": "Ye Olde Candy Shoppe", "city": "Cityville", "building": "1313", "street": "Vampire Lane", "zipcode": "99999", "storeSize": "large", "storeVisitDate": "5/3/12", "action": "Return", "dollarAmount": "65.43" }, { "storeID": "53454447", "storeName": "Ye Olde Candy Shoppe", "city": "Cityville", "building": "1313", "street": "Vampire Lane", "zipcode": "99999", "storeSize": "large", "storeVisitDate": "5/3/12", "action": "Purchase", "dollarAmount": "12.43" }, { "storeID": "53454447", "storeName": "Ye Olde Candy Shoppe", "city": "Cityville", "building": "1313", "street": "Vampire Lane", "zipcode": "99999", "storeSize": "large", "storeVisitDate": "5/3/12", "action": "Purchase", "dollarAmount": "5.43" }] }, { "key": "12/31/12", "values": [{ "storeID": "53454447", "storeName": "Ye Olde Candy Shoppe", "city": "Cityville", "building": "1313", "street": "Vampire Lane", "zipcode": "99999", "storeSize": "large", "storeVisitDate": "12/31/12", "action": "Purchase", "dollarAmount": "2.53" }] }, { "key": "1/24/13", "values": [{ "storeID": "53454447", "storeName": "Ye Olde Candy Shoppe", "city": "Cityville", "building": "1313", "street": "Vampire Lane", "zipcode": "99999", "storeSize": "large", "storeVisitDate": "1/24/13", "action": "Return", "dollarAmount": "2.53" }, { "storeID": "53454447", "storeName": "Ye Olde Candy Shoppe", "city": "Cityville", "building": "1313", "street": "Vampire Lane", "zipcode": "99999", "storeSize": "large", "storeVisitDate": "1/24/13", "action": "Return", "dollarAmount": "64.22" }] }] }, { "storeName": "Mike's Bikes", "address": "2626 Aardvark Circle, Townsville NY 88888", "zipCode": "88888", "storeSize": "small", "visits": [{ "key": "8/8/14", "values": [{ "storeID": "24335234", "storeName": "Mike's Bikes", "city": "Townsville", "building": "2626", "street": "Aardvark Circle", "zipcode": "88888", "storeSize": "small", "storeVisitDate": "8/8/14", "action": "Purchase", "dollarAmount": "443.55" }, { "storeID": "24335234", "storeName": "Mike's Bikes", "city": "Townsville", "building": "2626", "street": "Aardvark Circle", "zipcode": "88888", "storeSize": "small", "storeVisitDate": "8/8/14", "action": "Purchase", "dollarAmount": "34" }, { "storeID": "24335234", "storeName": "Mike's Bikes", "city": "Townsville", "building": "2626", "street": "Aardvark Circle", "zipcode": "88888", "storeSize": "small", "storeVisitDate": "8/8/14", "action": "Purchase", "dollarAmount": "12.32" }] }, { "key": "10/3/15", "values": [{ "storeID": "24335234", "storeName": "Mike's Bikes", "city": "Townsville", "building": "2626", "street": "Aardvark Circle", "zipcode": "88888", "storeSize": "small", "storeVisitDate": "10/3/15", "action": "Purchase", "dollarAmount": "233.1" }, { "storeID": "24335234", "storeName": "Mike's Bikes", "city": "Townsville", "building": "2626", "street": "Aardvark Circle", "zipcode": "88888", "storeSize": "small", "storeVisitDate": "10/3/15", "action": "Return", "dollarAmount": "44.99" }] }] }]; fixData(stores);
如果我們假設您的數組稱為arr,我建議:
arr.forEach(function(currentValue, index, array) { currentValue.visits = currentValue.visits.map(function(currentValue, index, array) { currentValue.visitDate = currentValue.key; delete currentValue.key; currentValue.transactions = currentValue.values.map(function(currentValue, index, array) { currentValue = {action: currentValue.action, dollars: currentValue.dollarAmount}; return currentValue; }); delete currentValue.values; return currentValue; }); });
好吧,由於這是“數據”,而不是某些內存中的對象,所以我猜您是通過使用JSON.parse
從JSON獲得的。 (如果沒有,您仍然可以通過首先使用JSON.strigify
來使用此方法)
您知道JSON.parse
接受用於控制此類事件的函數嗎? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
所以....
fixed=JSON.parse(dataString, function(key,value){
if(key=="key"){this.visitDate=value;return}
if(key=="values"){this.transactions=value;return}
if(key=="somethingYouDontWant"){return;}
//etc...
return value;
})
它純凈的javascript,沒有任何庫,並使用簡單的地圖:
var y = x.map(function(xs){
xs.visits = xs.visits.map(function (item){
return {
visitDate: item.key,
transactions: item.values.map(function(v){
return {
action: v.action,
dollars: v.dollarAmount
};
})
};
});
return xs;
});
Array.map()
和delete
運算符的靈活解決方案:
var delete_props = ["storeID","storeName","city","building","street", "zipcode","storeSize", "storeVisitDate"];
// arr is your initial array
arr.map(function(obj){
obj['visits'].map(function(inner_obj){
inner_obj['visitDate'] = inner_obj['key'];
delete inner_obj['key'];
inner_obj['values'].map(function(values_obj){
values_obj['dollars'] = values_obj['dollarAmount'];
delete values_obj['dollarAmount'];
delete_props.forEach(function(v){
delete values_obj[v];
});
});
inner_obj['transactions '] = inner_obj['values'];
delete inner_obj['values'];
});
});
這是另一種解決方案,代碼非常簡單,但尚未優化。
var obj = {}, key;
data.forEach(item => {
item.visits.forEach(visit => {
visit.visitDate = visit.key;
delete visit.key;
visit.transactions = [];
visit.values.forEach(value => {
obj = {};
for (key in value) {
if (value.hasOwnProperty(key) && retain.indexOf(key) > -1) {
obj[key] = value[key];
}
}
visit.transactions.push(obj);
});
delete visit.values;
});
console.log(item);
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.