Javascript 如何遍历复杂的Json对象,并对每个属性执行等于某个值的操作
我有以下问题 我需要遍历一个大的Json对象(子节点由数组、字符串和对象组成,根据嵌套属性至少有4-5层的深度) 在大Json文件的某些部分有一个特定的对象结构,它有一个名为“erpCode”的属性。我需要扫描Json并找到所有具有该属性的对象,获取值并使用该代码向其他API询问详细信息,一旦获得详细信息,就使用当前的“erpCode”将它们插入到对象中 只是澄清一下,在我的例子中,Json中的父节点属性名称始终等于“typeSysname”字段中的值,该字段与erpCode属性位于同一“级别”。 一个简单的例子:Javascript 如何遍历复杂的Json对象,并对每个属性执行等于某个值的操作,javascript,arrays,node.js,json,object,Javascript,Arrays,Node.js,Json,Object,我有以下问题 我需要遍历一个大的Json对象(子节点由数组、字符串和对象组成,根据嵌套属性至少有4-5层的深度) 在大Json文件的某些部分有一个特定的对象结构,它有一个名为“erpCode”的属性。我需要扫描Json并找到所有具有该属性的对象,获取值并使用该代码向其他API询问详细信息,一旦获得详细信息,就使用当前的“erpCode”将它们插入到对象中 只是澄清一下,在我的例子中,Json中的父节点属性名称始终等于“typeSysname”字段中的值,该字段与erpCode属性位于同一“级别”
{
"cars": [
{
"name": "X222",
"carType": {
"erpCode": "skoda",
"value": null,
"typeSysName": "carType"
}
}
],
"model": {
"year": 1999,
"details": {
"erpCode": "112"
"value": null,
"typeSysName": "details"
}
}
}
在这个例子中,我需要找到两个属性,从中获取值skoda和112,从不同的API获取值和描述数据,并将其设置到这个Json的正确位置
还有,有没有可能有一个好的npm包可以帮我解决这个问题
编辑:
几个月前,我得到了一个C#解决方案,它在Json上以通用方式运行,并以通用方式处理结构的复杂性。
但是我现在需要把它转换成Javascript,我有点迷路了
public static string TranslateDocErpCodes(string jsonString, string topRetailerSysName)
{
try
{
var doc = JObject.Parse(jsonString);
var erpCodeList = doc.SelectTokens("$..erpCode").ToList();
foreach (var erpCodeJToken in erpCodeList)
{
var value = erpCodeJToken?.Value<string>();
var erpCodeParent = erpCodeJToken?.Parent.Parent;
var erpCodeProperty = erpCodeParent?.Path.Split(".").Last();
var result =
_dataService.GetLovFromErpCode(topRetailerSysName, erpCodeProperty, value);
if (result == null)//reset lov obj
{
if (erpCodeParent?.Parent is JProperty prop)
prop.Value = JObject.FromObject(new LovObject { ErpCode = value });
}
else//set lov obj
{
result.ErpCode = value;
if (erpCodeParent?.Parent is JProperty prop)
prop.Value = JObject.FromObject(result);
}
}
return JsonConvert.SerializeObject(doc);
}
catch (Exception e)
{
throw new Exception("ErpConvert.TranslateDocErpCodes() : " + e);
}
}
公共静态字符串translatedCerpCodes(字符串jsonString,字符串topRetailerSysName)
{
尝试
{
var doc=JObject.Parse(jsonString);
var erpCodeList=doc.SelectTokens(“$…erpCode”).ToList();
foreach(erpCodeList中的变量erpCodeJToken)
{
var value=erpCodeJToken?.value();
var erpCodeParent=erpCodeJToken?.Parent.Parent;
var erpCodeProperty=erpCodeParent?.Path.Split(“.”.Last();
var结果=
_GetLovFromErpCode(topRetailerSysName、erpCodeProperty、value);
if(result==null)//重置lov obj
{
if(erpCodeParent?.Parent为JProperty属性)
prop.Value=JObject.FromObject(新对象{ErpCode=Value});
}
else//set lov obj
{
result.ErpCode=值;
if(erpCodeParent?.Parent为JProperty属性)
prop.Value=JObject.FromObject(结果);
}
}
返回JsonConvert.SerializeObject(单据);
}
捕获(例外e)
{
抛出新异常(“ErpConvert.TranslatedCerpCodes():”+e);
}
}
mb类似
function processObject(jsonData) {
for (prop in jsonData) {
if (jsonData.hasOwnProperty(prop)) {
// We get our prop
if (prop === 'code') {
let codeValue = jsonData[prop]
doSomeAsync(codeValue)
.then(response => {
jsonData[prop] = response;
})
}
let curValue = jsonData[prop];
if (Array.isArray(curValue)) {
// Loop through the array, if array element is an object, call processObject recursively.
processArray(curValue);
} else if (typeof curValue === 'object') {
processObject(curValue);
}
}
}
}
我以阿拉文德的答案为出发点,设法找到了似乎是一个完整的解决方案。 我会在这里分享
async function convertErpCodes(jsonData, orgName, parentPropertyName){
for (let prop in jsonData) {
if (jsonData.hasOwnProperty(prop)) {
if (prop === 'erpCode') {
const erpCodeValue = jsonData[prop]
const req = {"query": {"erpCode": erpCodeValue, "orgName": orgName, "typeSysName": parentPropertyName}};
const result = await viewLookupErpService.findOne(req);
if(result)
return result;
}
const curValue = jsonData[prop];
if (Array.isArray(curValue)) {
for(let i in curValue){
const res = await convertErpCodes(curValue[i], orgName, prop);
}
} else if (curValue && typeof curValue === 'object') {
const response = await convertErpCodes(curValue, orgName, prop);
if(response){
jsonData[prop] = response;
}
}
}
}
}
附言。
我只在从第三方API获得响应时设置值(这是递归中的结果和响应逻辑的原因。我将结合使用and
//const objectScan=require('object-scan');
//const lodash=需要(“lodash”);
const stats={cars:[{name:'X222',carType:{erpCode:'skoda',value:null,typeSysName:'carType'}}],model:{year:1999,details:{erpCode:'112',value:null,typeSysName:'details'}};
const entries=objectScan(['**.erpCode'],{rtn:'entry'})(stats);
控制台日志(条目);
//=>[[['车型','详细信息','erpCode'],'112'],[[['汽车','0','carType','erpCode'],'skoda']]
//您将在其中查询外部api并将结果放入条目中
条目[0][1]=“foo”;
分录[1][1]=“栏”;
entries.forEach(([k,v])=>lodash.set(stats,k,v));
console.log(stats);
//=>{cars:[{name:'X222',carType:{erpCode:'bar',value:null,typeSysName:'carType'}}],model:{year:1999,details:{erpCode:'foo',value:null,typeSysName:'details'}}}
。作为控制台包装{最大高度:100%!重要;顶部:0}
第二个对象是否应该在cars
数组中?也许类似的东西可以工作?错误的语言@SercanPaspal.nope,基本上Json是非常复杂的,它是一个对象,它包含多个数组和对象以及简单字符串,在这些对象和字符串中,它包含更多的对象和数组。我实际上得到了一个工作的C解决方案,但我现在需要将其“转换”为node.js,我在这样做时遇到问题。你的C#解决方案是什么?你能将其编辑成你的问题吗?