使用 JSON 中的动态多维键值对
Working With Dynamic Multidimensional key-value pairs in JSON
有一个棘手的问题,只在 SO 上看到类似但更简单的解决方案。
是否可以使用 JS/JSON 生成动态键和动态值?
例如,假设我有这样的 JSON:
{
"email": "user@someco.com",
"firstname": "Bob",
"lastname": "Smith",
"company": "ACME",
"custom": {
"services": [
{
"name": "svc1",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc2",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc3",
"desc": "abcdefg",
"selected": "false",
"status": "None"
},
{
"name": "svc4",
"desc": "abcdefg",
"selected": "false",
"status": "None"
}
],
"fields": [
{
"name": "Products",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Product1",
"desc": "abcdef"
},
{
"name": "Product2",
"desc": "abcdef"
}
],
"services": [
"svc1",
"svc2",
"svc3"
]
},
{
"name": "Wines",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Wine 1",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
},
{
"name": "Fruits",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Fruit 1",
"desc": "abcdef"
},
{
"name": "Fruit 2",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
}
]
}
};
我需要进入字段并针对每个字段(产品、葡萄酒、水果)查看是否包含给定服务,以便我可以返回并为需要的每个服务生成产品或葡萄酒或水果它。但我不想多次重复服务名称。结果 JSON 应该看起来像这样:
{"svc1":["Products"], "svc2":["Products"], "svc3":["Products"], "svc4":["Fruits", "Wines"]}
我希望在 Angular 中生成一个动态列表,我可以通过这个 JSON 循环并返回,提取每种产品、水果、葡萄酒等的值。
我一直在尝试很多嵌套的 for 循环等,但每当我向下超过一层时,活力似乎就停止了。我猜想为了让它工作,我需要在 JS 对象和 JSON 之间移动?
现在我正在尝试类似这样的方法,无论是否进行字符串化,它都不太有效。也许我在 JSON 和 JS 对象之间摇摆不定:
var outObj = [];
var fieldItems;
$.each(jsonObj.custom.fields, function(key, item) {
fieldItems = item;
fieldItems.name = item.name;
$.each(fieldItems.services, function(key, item) {
var serviceName = item;
//check to see if the serviceName already exists
if (outObj.indexOf(serviceName) > -1) {
outObj.serviceName.push(fieldItems.name);
} else {
outObj.push(serviceName);
}
});
});
JSON.stringify(outObj);
console.log("outObj " + outObj);
我收到 "can't read property 'push' of undefined" 错误之类的。似乎这应该可以从单个嵌套循环中实现,但也许我只需要进行两次传递?还有其他建议吗?
对我来说,这听起来像是过于复杂的解决方案。您可以使用 javascript 的基本数组方法来过滤出所需的结构。我不确定呈现的片段中的 profiling_value
是什么,所以我从 OP
中的对象结构开始
var desiredResult = jsonObj.custom.services.reduce(function(result, service){
result[service.name] = jsonObj.custom.fields.filter(function(field){
return field.services.indexOf(service.name) >= 0;
}).map(function(field){ return field.name; });
return result;
}, {});
这给出了上述对象的预期结果。
需要 reduce
遍历所有服务并将结果累积到一个对象中。然后对于每个服务字段迭代到 filter
只有那些包含 link 的服务。最后,过滤字段列表被转换 (map
) 为字符串列表 - 它们的名称 - 并插入累加器
有一个棘手的问题,只在 SO 上看到类似但更简单的解决方案。
是否可以使用 JS/JSON 生成动态键和动态值?
例如,假设我有这样的 JSON:
{
"email": "user@someco.com",
"firstname": "Bob",
"lastname": "Smith",
"company": "ACME",
"custom": {
"services": [
{
"name": "svc1",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc2",
"desc": "abcdefg",
"selected": "true",
"status": "None"
},
{
"name": "svc3",
"desc": "abcdefg",
"selected": "false",
"status": "None"
},
{
"name": "svc4",
"desc": "abcdefg",
"selected": "false",
"status": "None"
}
],
"fields": [
{
"name": "Products",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Product1",
"desc": "abcdef"
},
{
"name": "Product2",
"desc": "abcdef"
}
],
"services": [
"svc1",
"svc2",
"svc3"
]
},
{
"name": "Wines",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Wine 1",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
},
{
"name": "Fruits",
"desc": "abcdef",
"type": "multi",
"values": [
{
"name": "Fruit 1",
"desc": "abcdef"
},
{
"name": "Fruit 2",
"desc": "abcdef"
}
],
"services": [
"svc4"
]
}
]
}
};
我需要进入字段并针对每个字段(产品、葡萄酒、水果)查看是否包含给定服务,以便我可以返回并为需要的每个服务生成产品或葡萄酒或水果它。但我不想多次重复服务名称。结果 JSON 应该看起来像这样:
{"svc1":["Products"], "svc2":["Products"], "svc3":["Products"], "svc4":["Fruits", "Wines"]}
我希望在 Angular 中生成一个动态列表,我可以通过这个 JSON 循环并返回,提取每种产品、水果、葡萄酒等的值。
我一直在尝试很多嵌套的 for 循环等,但每当我向下超过一层时,活力似乎就停止了。我猜想为了让它工作,我需要在 JS 对象和 JSON 之间移动?
现在我正在尝试类似这样的方法,无论是否进行字符串化,它都不太有效。也许我在 JSON 和 JS 对象之间摇摆不定:
var outObj = [];
var fieldItems;
$.each(jsonObj.custom.fields, function(key, item) {
fieldItems = item;
fieldItems.name = item.name;
$.each(fieldItems.services, function(key, item) {
var serviceName = item;
//check to see if the serviceName already exists
if (outObj.indexOf(serviceName) > -1) {
outObj.serviceName.push(fieldItems.name);
} else {
outObj.push(serviceName);
}
});
});
JSON.stringify(outObj);
console.log("outObj " + outObj);
我收到 "can't read property 'push' of undefined" 错误之类的。似乎这应该可以从单个嵌套循环中实现,但也许我只需要进行两次传递?还有其他建议吗?
对我来说,这听起来像是过于复杂的解决方案。您可以使用 javascript 的基本数组方法来过滤出所需的结构。我不确定呈现的片段中的 profiling_value
是什么,所以我从 OP
var desiredResult = jsonObj.custom.services.reduce(function(result, service){
result[service.name] = jsonObj.custom.fields.filter(function(field){
return field.services.indexOf(service.name) >= 0;
}).map(function(field){ return field.name; });
return result;
}, {});
这给出了上述对象的预期结果。
需要reduce
遍历所有服务并将结果累积到一个对象中。然后对于每个服务字段迭代到 filter
只有那些包含 link 的服务。最后,过滤字段列表被转换 (map
) 为字符串列表 - 它们的名称 - 并插入累加器