![](/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.