Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.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 嵌套的foreach/forloops,通过JSON循环提取值_Javascript_Json_Node.js - Fatal编程技术网

Javascript 嵌套的foreach/forloops,通过JSON循环提取值

Javascript 嵌套的foreach/forloops,通过JSON循环提取值,javascript,json,node.js,Javascript,Json,Node.js,我要在面对这个问题之前说,我不确定这是不是最好的方法,所以其他方法非常受欢迎 最终目标:通过调用woocommerce API并使用响应数据来存储购买的产品和配料列表 我正在调用woocommerce REST api,它为我提供了一大块JSON数据。JSON中有第_行项目。这些是购买的产品。嵌套在行中的项目是元数据,这是浇头,例如番茄或酱油 附加了一个JSON的图像 所以我要做的就是创造这样的东西 var testOrderItems = [{ title: "Fried Ch

我要在面对这个问题之前说,我不确定这是不是最好的方法,所以其他方法非常受欢迎

最终目标:通过调用woocommerce API并使用响应数据来存储购买的产品和配料列表

我正在调用woocommerce REST api,它为我提供了一大块JSON数据。JSON中有第_行项目。这些是购买的产品。嵌套在行中的项目是元数据,这是浇头,例如番茄或酱油

附加了一个JSON的图像

所以我要做的就是创造这样的东西

var testOrderItems =
  [{
      title: "Fried Chicken Burger",
      meta: [
        "Lettuce",
        "cheese slice",
        "kethcup"
      ]
    },
    {
      title: "Beef Burger",
      meta: [
        "Lettuce",
        "cheese slice",
        "kethcup"
      ]
    }
  ]
它将遵循我的订单项目模式

var orderItems = new Schema({
    title: {type: String, required: true},
    meta: [{type: String}]

});
所以要做到这一点,我想我只需要通过JSON执行forloop或foreach来获取所有产品名称及其元数据。获取实际值很容易。最困难的部分是创建我可以存储的数组或JSON对象,我只是不知道如何在循环中创建它。下面是我尝试过的一些事情

let fullData = JSON.parse(result)

//parsed response from woocommerce API call

fullData.line_items.forEach((product, index) => {
  //for each line item get me the product
  orderItems.push(product.name)
  //var namey = 
  //push the product name to the orderItemsArray
  product.meta_data.forEach(function(meta) {
    //checks for string as one of the plug-ins fills the meta with more nested information and we only want the top level string
    if (typeof meta.value === 'string' || meta.value instanceof String)
      // it's a string
      orderItems.push(meta.value)
    //Onbviously won't nest the meta with the product name just on new lines
  })
});
我以为我可以在for循环中通过将ID ref存储为“I”并能够在嵌套循环中重新引用它来添加meta来实现这一点,我对此有点不知所措

var length = fullData.line_items.length

for (let i = 0; i < length; i++) {
  // console.log(i);
  console.log(fullData.line_items[i].name)
  for (let j = 0; j < fullData.line_items[i].meta_data.length; j++) {
    var metaValue = fullData.line_items[i].meta_data[j].value
    if (typeof metaValue === 'string' || metaValue instanceof String) {
     console.log(fullData.line_items[i].meta_data[j].value);
      stringMeta = fullData.line_items[i].meta_data[j].value
      //this works but has drawbacks
      //1 obviously just overwrites itself each time
      //2 will stop at the end of meta so won't add items without meta
      finalOrderItems = {
        id: i,
        name: fullData.line_items[i].name,
        meta: [stringMeta]
      }
    }
  }
}
var length=fullData.line\u items.length
for(设i=0;i

这就是我所处的位置,感觉这应该非常简单,但目前还不能完全理解。

您可以简单地创建表示模式的对象,然后从json对象的映射返回它。因此,它看起来如下所示:

let testOrderItems = fullData.line_items.map((product)=>{
     let obj = { name: product.name };
     obj.meta = product.meta_data.map((meta)=>{
         if (typeof meta.value === 'string' || meta.value instanceof String)
          return meta.value;
     }).filter((value)=>!!value);
    return obj;
})
console.log(testOrderItems);

尽管如此,if语句似乎有点多余,因为woocommerceapi将只包含meta或不包含meta。但是,您可能有一些插件或其他东西,它们正在向元区域添加更多信息,因此我将其保留在我的示例中

这看起来像是
map
reduce
的作业,而不是
forEach
<代码>映射
行项目的每个对象映射到一个新对象中,
减少
将通过
键对每个对象的元进行分组和组织:

var orderItems = fullData.line_items.map(function(product) {      // map each product in line_items
    return {                                                      // into a new object
        title: product.name,                                      // with title equals to the current product's name
        meta: product.meta_data.reduce(function(acc, meta) {      // and metas accumulated from each meta object in the current product's meta_data array
            acc[meta.key] = acc[meta.key] || [];                  // first, check if there is an array for the current meta's key in the group object 'acc', if not create one
            acc[meta.key].push(meta.value);                       // add the current meta's value to that array
            return acc;
        }, {})
    }
});
使用箭头功能:

var orderItems = fullData.line_items.map(product => ({
    title: product.name,
    meta: product.meta_data.reduce((acc, meta) => {
        acc[meta.key] = acc[meta.key] || [];
        acc[meta.key].push(meta.value);
        return acc;
   }, {})
}));

元对象的值不能是字符串吗?为什么您需要测试
typeof metaValue==='string'| | metaValue instanceof string
?您应该发布一个实际的json,而不是发布一个json图像,这样人们可以使用它来尝试和测试他们的答案您确定要将所有的meta值放在一个数组中吗?它们不应该按元键进行组织,例如,
配料:[“莴苣”、“奶酪片”、“番茄酱”]
按元键进行组织很好。同样关于JSON的评论,抱歉文件太大,所以不想添加它,也没有看到任何可以附加JSON文件的地方。@user2389087那么我们走Barmar的路了吗?按键组织Meta?这很有效,对我来说稍微有点修改,我不得不使用“fullData.line\u items.map”。此外,还有一个附加组件插件,它向元区域添加了大量冗余信息。谢谢你带我去学校:)太棒了!很高兴我能帮忙。我将编辑我的帖子以反映这一变化干杯谢谢,又是一个很好的回答和解释。你完全正确,这不是forEach的工作