Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何遍历复杂的Json对象,并对每个属性执行等于某个值的操作_Javascript_Arrays_Node.js_Json_Object - Fatal编程技术网

Javascript 如何遍历复杂的Json对象,并对每个属性执行等于某个值的操作

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属性位于同一“级别”

我有以下问题

我需要遍历一个大的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#解决方案是什么?你能将其编辑成你的问题吗?