首先,我不确定这是否是最好的方法,所以其他方法将受到赞赏
最终目标:存储通过调用woocommerce API并使用响应数据购买的产品和浇头的列表
我正在调用woocommerce REST API,它为我提供了大量的JSON数据。 JSON中有line_items。这些是购买的产品。嵌套在line_items中的是meta_data,这是浇头,例如番茄或调味酱。
的图像所以我想做的就是创建这样的东西
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
})
});
我想我可以通过将ID ref存储为“ i”并在嵌套循环中稍后重新引用以添加meta的方式在for循环中做到这一点,我对此有些迷茫
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]
}
}
}
}
这就是我所在的位置,感觉这应该非常容易,但目前还不太了解。
答案 0 :(得分:1)
您可以简单地先创建代表您的模式的对象,然后从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语句似乎有点多余,因为woocommerce api将仅具有meta或不具有meta。但是,您可能有一些插件或正在向meta区域添加更多信息的东西,因此我将其保留在示例中。
答案 1 :(得分:0)
这看起来像是map
和reduce
而非forEach
的工作。 map
将line_items
的每个对象映射到一个新对象,而reduce
将按照key
对每个对象的meta进行分组和组织:
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;
}, {})
}));