我的产品看起来像这样:
{
"productId": 5256502,
"name": "360fly - 4K Action Camera",
"light": true,
"wiFi": true,
"colour": "Black"
}
我有一些看似这样的标准:
_criteria = [
{
"id": 38,
"type": "Boolean",
"name": "Light",
"states": [
{
"id": 93,
"criteriaId": 38,
"name": "False"
},
{
"id": 94,
"criteriaId": 38,
"name": "True"
}
]
},
{
"id": 41,
"type": "Boolean",
"name": "New",
"states": [
{
"id": 95,
"criteriaId": 41,
"name": "True"
},
{
"id": 96,
"criteriaId": 41,
"name": "False"
}
]
},
{
"id": 42,
"type": "Boolean",
"name": "Available",
"states": [
{
"id": 97,
"criteriaId": 42,
"name": "True"
},
{
"id": 98,
"criteriaId": 42,
"name": "False"
}
]
}
];
条件按名称映射到产品。例如,如果我有一个名为 Light 的标准,那么我应该在产品中有一个名为 light 的相应字段。 所以,我正在尝试构建一个检查出来的函数。
我试图遍历所有产品属性,如下所示:
// For each property in our product
for (var property in product) {
// If we have a property and it doesn't start with an underscore
if (product.hasOwnProperty(property) && property.substring(0, 1) !== '_' && property !== 'productId' && property !== 'name') {
}
}
然后我将循环遍历条件并匹配名称(将其转换为 camelCase 之后)。但我需要以相反的方式比较它,所以我必须遍历所有标准,看看是否存在产品中不存在的标准。
我希望有一种更好的方法可以做到这一点,而不是遍历所有产品,然后循环遍历所有标准和匹配,一旦完成,循环所有标准,然后遍历所有产品。
有没有人知道如何帮助我?
答案 0 :(得分:0)
你可以采用嵌套几个for循环的方法,然后从两个数组中删除匹配的元素以进行下一次迭代。这会减少开销量,因为每次迭代时阵列都会变小。
使用Monkey-Patching,我们可以确保将属性元素读为lowercase
:
Object.prototype.hasOwnPropertyCI = function(prop) {
return Object.keys(this)
.filter(function (v) {
return v.toLowerCase() === prop.toLowerCase();
}).length > 0;
};
接下来在必要时迭代两个数组和拼接。 在这些嵌套的for循环迭代之后,两个数组应该只包含在另一个数组中不匹配的元素。
for(var i = 0; i < _criteria.length; i++){
for(var j = 0; j < product.length; j++){
if(product[j].hasOwnProperty(_criteria[i].name.toLowerCase())){
product.splice(j,1);
_criteria.splice(i,1);
j--;
i--;
}
}
}
这是一个小提琴:https://jsfiddle.net/p1c4kdhv/1/
基本上我在这里做的是每次找到匹配时减小样本大小。因此,下一次迭代将需要较少数量的比较,这可以提高效率。
请注意,如果存在特定属性类型的多个比较,则可以修改此中心方法。只需修改数组中拼接的循环中的位置,然后发生减量。
答案 1 :(得分:0)
有点不清楚你在问什么。但我认为您要问的是产品符合哪些标准。此代码段将返回在产品中为真的条件名称数组。
let output = [];
_criteria.forEach(item => {
const {name} = item;
output = output.concat(Object.keys(product).filter(key => {
return product[key] === true && key.toLowerCase() === name.toLowerCase();
}));
});
// returns ['light'] using your test data because only light is true and is in the criteria list