【问题标题】:Loop through json and fetch specific values in nodejs循环 json 并在 nodejs 中获取特定值
【发布时间】:2020-02-12 09:25:12
【问题描述】:

我有一个场景,我试图通过下面的 json 解析并获取 key "name" 和 key "id" 的所有值,我会进一步将它们存储在变量或数组中。

  [
      {
        "metadata": {
          "id": "vvvvvvvvvvvvv",
          "url": "cccccccccccccc",
          "created_at": "2019-09-06T08:40:41Z",
          "updated_at": "2019-09-06T13:25:46Z"
        },
        "entity": {
          "name": "app1",
          "b_enabled": false,
          "d_url": "xxxxxs"
        }
      },
        {
        "metadata": {
          "id": "vvvvvvvvvvccc",
          "url": "cccccccccccccc",
          "created_at": "2019-09-06T08:40:41Z",
          "updated_at": "2019-09-06T13:25:46Z"
        },
        "entity": {
          "name": "app2",
          "b_enabled": false,
          "d_url": "xxxxxs"
        }
      },
        {
        "metadata": {
          "id": "vvvvvvvvvvddd",
          "url": "cccccccccccccc",
          "created_at": "2019-09-06T08:40:41Z",
          "updated_at": "2019-09-06T13:25:46Z"
        },
        "entity": {
          "name": "app3",
          "b_enabled": false,
          "d_url": "xxxxxs"
        }
      },
        {
        "metadata": {
          "id": "vvvvvvvvvveee",
          "url": "cccccccccccccc",
          "created_at": "2019-09-06T08:40:41Z",
          "updated_at": "2019-09-06T13:25:46Z"
        },
        "entity": {
          "name": "app4",
          "b_enabled": false,
          "d_url": "xxxxxs"
        }
      },
        {
        "metadata": {
          "id": "vvvvvvvvvvfff",
          "url": "cccccccccccccc",
          "created_at": "2019-09-06T08:40:41Z",
          "updated_at": "2019-09-06T13:25:46Z"
        },
        "entity": {
          "name": "app5",
          "b_enabled": false,
          "d_url": "xxxxxs"
        }
    }
    ]

我到目前为止所尝试的(在此之后不确定如何进行,因为这本身提供了错误的结果)

 const dJSON = require('dirty-json');

 const jsn = dJSON.parse(get_all)
 console.log(JSON.stringify(jsn));
 jsonData = JSON.stringify(jsn)
 console.log(jsonData.length) //this returns wrong value

for(var i = 0; i < jsonData.length; i++){
    for(key in jsonData[i].entity){
      if(jsonData[i].entity[key] == "name"){
          return console.log(key);
          }
      }
}

这不会返回预期的输出。 有人可以在这里提出建议,因为我是 nodejs 和 javascript 的新手,如何提取这样的结果

预期 o/p :

{ 
  "app1"   :  "vvvvvvvvvvvvv", 
  "app2"   :  "vvvvvvvvvvccc",
  "app3"   :  "vvvvvvvvvvddd",
  "app4"   :  "vvvvvvvvvveee",
  "app5"   :  "vvvvvvvvvvfff" 
}

【问题讨论】:

  • metadata 键和entity 键是否始终相同
  • @Nicolas 确实

标签: javascript arrays node.js json loops


【解决方案1】:

在输出中

key = entity.name

val = metadata.id

每个文档

方法很简单。 Intilize 一个空的对象。将 key, val 放入空对象中。

var result = {}
jsonData.forEach(x => {
   result[x.entity.name]= x.metadata.id
})

https://jsfiddle.net/v8w2L1oa/

【讨论】:

  • 您好,您能否添加有关您的答案的更多信息?
  • 这返回一个数组,问题要求返回一个对象
  • @DanStarns 嘿,你能检查一下 js 文件吗?你会得到明确的答案。
【解决方案2】:
  const jsObj = JSON.parse(json);
  const result = jsObj.map(entry => ({name: entry.entity.name, id: entry.metadata.id}));
  const objResult = {};
  result.forEach(entry => {
    objResult[entry.name] = entry.id;
  });
  console.log(objResult);

输出:

{ app1: 'vvvvvvvvvvvvv',
  app2: 'vvvvvvvvvvccc',
  app3: 'vvvvvvvvvvddd',
  app4: 'vvvvvvvvvveee',
  app5: 'vvvvvvvvvvfff' }

【讨论】:

  • 您好,您能否添加有关您的答案的更多信息?
【解决方案3】:

这里我使用JSON.parse,所以我可以在数据上使用Array.map方法,我在传递给映射的回调中使用Object destructuring将值metadata.identity.name拉到函数的范围内。然后我返回一个以entity.name 作为键和metadata.id 作为值的对象。 map 的返回值是一个新数组,因此我可以使用Array.reduce 将数组转换为不同的数据结构。在reduce 的每次迭代中,参数current 将是从map 的每次迭代中返回的单个对象。因为Object.keys(current) 的长度始终为 1,所以我可以使用解构来提取唯一的键名并使用 key/name 填充返回对象。

const json = `[
    {
      "metadata": {
        "id": "vvvvvvvvvvvvv",
        "url": "cccccccccccccc",
        "created_at": "2019-09-06T08:40:41Z",
        "updated_at": "2019-09-06T13:25:46Z"
      },
      "entity": {
        "name": "app1",
        "b_enabled": false,
        "d_url": "xxxxxs"
      }
    },
      {
      "metadata": {
        "id": "vvvvvvvvvvccc",
        "url": "cccccccccccccc",
        "created_at": "2019-09-06T08:40:41Z",
        "updated_at": "2019-09-06T13:25:46Z"
      },
      "entity": {
        "name": "app2",
        "b_enabled": false,
        "d_url": "xxxxxs"
      }
    },
      {
      "metadata": {
        "id": "vvvvvvvvvvddd",
        "url": "cccccccccccccc",
        "created_at": "2019-09-06T08:40:41Z",
        "updated_at": "2019-09-06T13:25:46Z"
      },
      "entity": {
        "name": "app3",
        "b_enabled": false,
        "d_url": "xxxxxs"
      }
    },
      {
      "metadata": {
        "id": "vvvvvvvvvveee",
        "url": "cccccccccccccc",
        "created_at": "2019-09-06T08:40:41Z",
        "updated_at": "2019-09-06T13:25:46Z"
      },
      "entity": {
        "name": "app4",
        "b_enabled": false,
        "d_url": "xxxxxs"
      }
    },
      {
      "metadata": {
        "id": "vvvvvvvvvvfff",
        "url": "cccccccccccccc",
        "created_at": "2019-09-06T08:40:41Z",
        "updated_at": "2019-09-06T13:25:46Z"
      },
      "entity": {
        "name": "app5",
        "b_enabled": false,
        "d_url": "xxxxxs"
      }
  }
  ]`;

const result = JSON.parse(json)
    .map(({ metadata: { id }, entity: { name } }) => {
        return { [name]: id };
    })
    .reduce((prev, current) => {
        const [name] = Object.keys(current);

        prev[name] = current[name];

        return prev;
    }, {});

console.log(result);

【讨论】:

  • 嗨,你能补充一点关于你的答案的信息吗?只提供代码没有帮助。
  • 你的代码返回这个结果{ app1: undefined, app2: undefined, 'app3': undefined, app4: undefined, app5: undefined }
  • @Thomas 你确定,代码 sn-p 工作正常。
  • @Nicolas 请看说明
  • @Thomas 您需要使用带有引号的 JSON 更新您的问题。仔细检查您的 JSON,因为它存在于您的数据中而不是您的问题中。
【解决方案4】:

欢迎使用 stackoverflow ! 您只需要循环一次 Json,然后获取每个元素的 metadata.identity.name

let json = [
      {
        "metadata": {
          "id": "vvvvvvvvvvvvv",
          "url": "cccccccccccccc",
          "created_at": "2019-09-06T08:40:41Z",
          "updated_at": "2019-09-06T13:25:46Z"
        },
        "entity": {
          "name": "app1",
          "b_enabled": false,
          "d_url": "xxxxxs"
        }
      },
        {
        "metadata": {
          "id": "vvvvvvvvvvccc",
          "url": "cccccccccccccc",
          "created_at": "2019-09-06T08:40:41Z",
          "updated_at": "2019-09-06T13:25:46Z"
        },
        "entity": {
          "name": "app2",
          "b_enabled": false,
          "d_url": "xxxxxs"
        }
      },
        {
        "metadata": {
          "id": "vvvvvvvvvvddd",
          "url": "cccccccccccccc",
          "created_at": "2019-09-06T08:40:41Z",
          "updated_at": "2019-09-06T13:25:46Z"
        },
        "entity": {
          "name": "app3",
          "b_enabled": false,
          "d_url": "xxxxxs"
        }
      },
        {
        "metadata": {
          "id": "vvvvvvvvvveee",
          "url": "cccccccccccccc",
          "created_at": "2019-09-06T08:40:41Z",
          "updated_at": "2019-09-06T13:25:46Z"
        },
        "entity": {
          "name": "app4",
          "b_enabled": false,
          "d_url": "xxxxxs"
        }
      },
        {
        "metadata": {
          "id": "vvvvvvvvvvfff",
          "url": "cccccccccccccc",
          "created_at": "2019-09-06T08:40:41Z",
          "updated_at": "2019-09-06T13:25:46Z"
        },
        "entity": {
          "name": "app5",
          "b_enabled": false,
          "d_url": "xxxxxs"
        }
    }
    ]
    
  
    let output = {};
    
    // we parse each element of the json array
    for(let i = 0; i < json.length; i ++ ) {
      // we get the current element.
      let currentElement = json[i];
      // here, we are using the name of the entity as the key and the id of the metadata as the value
      output[currentElement.entity.name] = currentElement.metadata.id;
    }
    
    console.log(output);

【讨论】:

    【解决方案5】:

    您可以使用简单的forEach() 函数来迭代您的数组。您可以使用当前迭代项来填充另一个对象,就像您在问题中要求的那样。

    所以首先你可以创建一个对象来存储过滤后的结果:

    output = {}

    接下来,您可以遍历数组并填充输出对象:

    your_array.forEach(item =&gt; {output[item.entity.name] = item.metadata.id})

    这将用键值对填充output 对象。

    所以它的具体作用是,对于your_array 中的每个item,它将执行(lambda)函数{output[item.entity.name] = item.metadata.id},其中item 是当前的迭代项。


    总代码:

    var output = {};
    your_array.forEach(item => {output[item.entity.name] = item.metadata.id});
    
    // output will now be: 
    //  { 
    //    "app1"   :  "vvvvvvvvvvvvv", 
    //    "app2"   :  "vvvvvvvvvvccc",
    //    "app3"   :  "vvvvvvvvvvddd",
    //    "app4"   :  "vvvvvvvvvveee",
    //    "app5"   :  "vvvvvvvvvvfff" 
    //  }
    

    【讨论】:

    • 它给出了以下错误Error: TypeError: jsonData.forEach is not a function
    • @thomas,那是因为你的jsonData 是一个字符串,而不是一个数组(因为你之前使用了JSON.stringify。使用你的变量jsn 而不是jsonData
    【解决方案6】:

    var arr=[
        {
          "metadata": {
            "id": "vvvvvvvvvvvvv",
            "url": "cccccccccccccc",
            "created_at": "2019-09-06T08:40:41Z",
            "updated_at": "2019-09-06T13:25:46Z"
          },
          "entity": {
            "name": "app1",
            "b_enabled": false,
            "d_url": "xxxxxs"
          }
        },
          {
          "metadata": {
            "id": "vvvvvvvvvvccc",
            "url": "cccccccccccccc",
            "created_at": "2019-09-06T08:40:41Z",
            "updated_at": "2019-09-06T13:25:46Z"
          },
          "entity": {
            "name": "app2",
            "b_enabled": false,
            "d_url": "xxxxxs"
          }
        },
          {
          "metadata": {
            "id": "vvvvvvvvvvddd",
            "url": "cccccccccccccc",
            "created_at": "2019-09-06T08:40:41Z",
            "updated_at": "2019-09-06T13:25:46Z"
          },
          "entity": {
            "name": "app3",
            "b_enabled": false,
            "d_url": "xxxxxs"
          }
        },
          {
          "metadata": {
            "id": "vvvvvvvvvveee",
            "url": "cccccccccccccc",
            "created_at": "2019-09-06T08:40:41Z",
            "updated_at": "2019-09-06T13:25:46Z"
          },
          "entity": {
            "name": "app4",
            "b_enabled": false,
            "d_url": "xxxxxs"
          }
        },
          {
          "metadata": {
            "id": "vvvvvvvvvvfff",
            "url": "cccccccccccccc",
            "created_at": "2019-09-06T08:40:41Z",
            "updated_at": "2019-09-06T13:25:46Z"
          },
          "entity": {
            "name": "app5",
            "b_enabled": false,
            "d_url": "xxxxxs"
          }
      }
      ]
      
      var myMap =new Map();
     
      arr.forEach((element,index)=>{
        var a= arr[index]
        var id='';
        var name='';
        
       var c= Object.keys(a).map(item=>{
         // console.log(item)
           if(item=="metadata"){
           id=a[item]["id"]
           
           }
          else{
             name=a[item]["name"]
             
             }
            }
       )
      myMap[name]=id;
          
         
      })
      console.log(myMap)
       
     

    好吧,这不是最佳和优化的解决方案(我对 js 太陌生),但这解决了您的问题陈述。我只是想获取作为对象的数组的每个元素,然后在每个对象中尝试获取个人的键并将其存储在变量中,然后将其推送到地图以获得所需的输出。附:使用您的输入作为 arr。

    【讨论】:

    • 你运行你的代码 sn-p 了吗?它会产生错误。
    • 在 Visual Studio 中显示输出。让我调试一下
    • 您没有在示例代码 sn-p 中包含 JSON。您可能需要更新您的代码 sn-p 或删除它,因为它不起作用。
    • @AyushiKeshri 我不确定,但是当我尝试这个时,它给了我Error: TypeError: arr.forEach is not a function
    • @Thomas 它在 vsc、codepen 和这里工作代码。所以可能是你做错了什么。同样常见的错误是输入是数组,如果你把它当作一个对象,那么每个对象都没有在这种情况下循环参考:stackoverflow.com/questions/31096596/…
    猜你喜欢
    • 2020-06-28
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多