如何使用普通 Javascript 访问双层嵌套 arrays/objects 的最内层?
How to access innermost levels of doubly nested arrays/objects using plain Javascript?
我想答案很简单,但我已经搜索过这个网站和其他网站,但没有找到。我有一个双层嵌套的数据结构,不知道如何遍历最内层。我猜它可能涉及 forEach() 或 map() 方法,但我没有尝试过。
背景:
我已经简化了这个问题的数据。数据(粘贴在下面)存储在一个包含 2 个零售店对象的数组中。每个商店对象都有一个 visits
属性 ,其值是一个访问对象数组。每次访问(对象)都由访问日期标识(假设在日期 B 最多可以有 1 次访问商店 A)。每个访问对象都包含一个 values
属性,其值是访问时进行的一组交易(购买或 returns)。在实际的全量数据中,每个商店每个日期的交易数量变化很大。
我需要帮助的任务:
(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"
}
]
}
]
}
]
要重命名属性,您可以创建一个与 delete
旧属性具有相同值的新属性。
您可以将它用于所有部分,但查看您的结构,通过使用 map()
创建新的 "optimised" 事务数组将 b、c、d 组合在一起看起来更整洁,并且将其分配给新的 transactions
属性.
// (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;
});
});
好吧,因为这是 'data' 而不是一些内存中的对象,我猜你是通过使用 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);
});
你说得对!您可以使用 .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 }))
};
})
});
});
(working example on jsFiddle here - 打开JS控制台就可以看到转换后的数据集)
关于以下解决方案的几点:
- 即使您的数据具有比您粘贴的示例中更多的键,它也会起作用(您提到这是一个简化的集合,因此它可能很重要)
它经常使用 "map",而不是手动遍历数组。我发现它更具可读性。
// 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
};
});
});
});
请注意 map() 受 IE9 及更新版本支持。
我想答案很简单,但我已经搜索过这个网站和其他网站,但没有找到。我有一个双层嵌套的数据结构,不知道如何遍历最内层。我猜它可能涉及 forEach() 或 map() 方法,但我没有尝试过。
背景:
我已经简化了这个问题的数据。数据(粘贴在下面)存储在一个包含 2 个零售店对象的数组中。每个商店对象都有一个 visits
属性 ,其值是一个访问对象数组。每次访问(对象)都由访问日期标识(假设在日期 B 最多可以有 1 次访问商店 A)。每个访问对象都包含一个 values
属性,其值是访问时进行的一组交易(购买或 returns)。在实际的全量数据中,每个商店每个日期的交易数量变化很大。
我需要帮助的任务:
(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"
}
]
}
]
}
]
要重命名属性,您可以创建一个与 delete
旧属性具有相同值的新属性。
您可以将它用于所有部分,但查看您的结构,通过使用 map()
创建新的 "optimised" 事务数组将 b、c、d 组合在一起看起来更整洁,并且将其分配给新的 transactions
属性.
// (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; }); });
好吧,因为这是 'data' 而不是一些内存中的对象,我猜你是通过使用 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);
});
你说得对!您可以使用 .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 }))
};
})
});
});
(working example on jsFiddle here - 打开JS控制台就可以看到转换后的数据集)
关于以下解决方案的几点:
- 即使您的数据具有比您粘贴的示例中更多的键,它也会起作用(您提到这是一个简化的集合,因此它可能很重要)
它经常使用 "map",而不是手动遍历数组。我发现它更具可读性。
// 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 }; }); }); });
请注意 map() 受 IE9 及更新版本支持。