JavaScript比较2个数组(各种)

时间:2016-05-24 17:11:32

标签: javascript

我的产品看起来像这样:

{
    "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 之后)。但我需要以相反的方式比较它,所以我必须遍历所有标准,看看是否存在产品中不存在的标准。

我希望有一种更好的方法可以做到这一点,而不是遍历所有产品,然后循环遍历所有标准和匹配,一旦完成,循环所有标准,然后遍历所有产品。

有没有人知道如何帮助我?

2 个答案:

答案 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

这是一个示例http://jsbin.com/wobuhiteja/edit?js,console