遍历不同结构的数组 JSON objects/arrays

Loop through array of differently structured JSON objects/arrays

我觉得这主要是我如何遍历 JSON 的问题,所以我先发帖。这是下面发布的来自 Promise.allSettled() 的一系列 JSON 回复。

我遇到的问题是 content 和 anoObject1 之间的第二个“状态”对象,因为我正在遍历 JSON 响应。我在下面展示了一些成功的 console.logs()

下面是一系列 JSON 回复:

[
    {
        "status": "fulfilled",
        "value": {
            "content": {
                "object1": {
                    "kv": "Y",
                    "kv1": "1000",
                    "kv2": {
                        "okv": "A",
                        "okv1": "1"
                    },
                    "kw": "A"
                }
            },
            "retrievalDate": "2022-05-04T23:01:57.710+0000"
        }
    },
    {
        "status": "fulfilled",
        "value": {
            "content": [
                {
                    "anoObject1": {
                        "ano": "A",
                        "ano1": {
                            "ona": "B",
                            "ona1": 11
                        },
                        "measureValue": "1.92",
                        "measureValue2": "N"
                    }
                },
                {
                    "anoObject2": {
                        "ano": "B",
                        "ano1": {
                            "ona": "Y",
                            "ona1": 11
                        },
                        "measureValue": "1.92",
                        "measureValue2": "N"
                    }
                }
            ],
            "retrievalDate": "2022-05-04T23:01:57.707+0000"
        }
    }
]

以下是异步提取调用:

export async function allCallouts(key, value){

    const BASE_URL = 'https://baseurl.com/service/'
    const API_KEY = 'apikey'
    const endpoint1 = 'https://url1.com/a/';
    const endpoint2 = 'https://url1.com/b/';
    

    try{
        const results = await Promise.allSettled(
            [
                fetch(endpoint1).then((response) => response.json()),
                fetch(endpoint2).then((response) => response.json()),
            ]
        )
        return results
    } catch (error){
        console.log(error)
    }
}

这是我从中调用第一个函数的函数

async handleFetchCallouts() {

    returnedResults;

    await allCallouts(key, value)
        .then(results => {

            this.returnedResults = results

        }).catch(err => {
            console.log('this is err: ' + err);
        })


    let arrayLength = this.returnedResults.length

    for (var i = 0; i < arrayLength; i++) {

        //I am able to console.log(this.returnedResults[i].value.content)
        //it returns the response and number I am expecting
        //but the structure of the JSON response (above) is tripping me up
        

        if (this.returnedResults[i].value.content['object1'] != null) {

            //I can console.log() this successfully
            console.log(this.returnedResults[i].value.content['object1'].kv)

        }

        if (this.returnedResults[i].value.content['anoObject1'] != null) {

            //having trouble getting to this object and looping through each

        }

    }

}

感谢您的帮助!如果您发现我的代码存在其他设计缺陷或更简单的方法,请提出建议。

您可以使用 Array.isArray() 确定对象是否 Array 并相应地自定义处理对象的方式。

// Same structure as in the question, but removed extraneous 
// fields and compacted for the sake of brevity.
const input = `[
    {"value":{"content":{"object1":{"kv":"Y"}}}},
    {"value":{"content":[
        {"anoObject1":{"ano":"A"}},
        {"anoObject1":{"ano":"B"}}
    ]}}]`;

const result = JSON.parse(input);
for (const r of result) {
  const content = r.value.content;
  if (Array.isArray(content)) {
    for (const c of content) {
      console.log(`anoObject1.ano = ${c.anoObject1.ano}`);
    }
  } else {
    console.log(`object1.kv = ${content.object1.kv}`);
  }
}

对于 for 循环中的第二个 if 语句,您必须遍历 value.content 下的所有项目。将第二个 if 语句替换为即插即用:

if (Array.isArray(this.returnedResults[i].value.content)) for (let i of this.returnedResults[i].value.content) {

}

在新循环中,i 将等同于

                {
                    "anoObject1": {
                        "ano": "A",
                        "ano1": {
                            "ona": "B",
                            "ona1": 11
                        },
                        "measureValue": "1.92",
                        "measureValue2": "N"
                    }
                }

原因是第二个 if 语句试图查找数组的 property/key 而不是对象数组中的每个对象。

我还建议您阅读以下内容来编写代码 easier/better:

创建一个 recursive 函数并且不使用任何硬编码密钥。遍历内容并使用 Array.isArray 检查值是否为数组。如果是这样,那么在不同的函数中处理它,如果值是 object

类型

const arrayLength = [{
    "status": "fulfilled",
    "value": {
      "content": {
        "object1": {
          "kv": "Y",
          "kv1": "1000",
          "kv2": {
            "okv": "A",
            "okv1": "1"
          },
          "kw": "A"
        }
      },
      "retrievalDate": "2022-05-04T23:01:57.710+0000"
    }
  },
  {
    "status": "fulfilled",
    "value": {
      "content": [{
          "anoObject1": {
            "ano": "A",
            "ano1": {
              "ona": "B",
              "ona1": 11
            },
            "measureValue": "1.92",
            "measureValue2": "N"
          }
        },
        {
          "anoObject1": {
            "ano": "B",
            "ano1": {
              "ona": "Y",
              "ona1": 11
            },
            "measureValue": "1.92",
            "measureValue2": "N"
          }
        }
      ],
      "retrievalDate": "2022-05-04T23:01:57.707+0000"
    }
  }
]
for (let i = 0; i < arrayLength.length; i++) {
  const content = arrayLength[i].value.content;
  // checking if value is of type array or object
  if (Array.isArray(content)) {
    handleContentArray(content)

  } else if (content && typeof(content) === 'object') {
    handleContentObject(content)
  }
}

function handleContentArray(contentArray) {
  // iterate the array
  contentArray.forEach(item => {
    // if the content of the array is an object then call the function which handles the object
    if (item && typeof item === 'object') {
      handleContentObject(item)
    }
  })
}

function handleContentObject(contentObject) {
  // iterate through the key
  for (let keys in contentObject) {
    // if the value of the key is an object then recursively call the same function
    if (contentObject && typeof(contentObject[keys]) === 'object') {
      return handleContentObject(contentObject[keys])
    } else {
      // log the key value pair
      console.log(`KEY:- ${keys}, VALUE: - ${contentObject[keys]}`)

    }
  }
}