过滤具有多个属性的两个数组

时间:2016-04-06 15:18:06

标签: javascript arrays

请参阅下面的两个数组,首先我们将修复数组发送到后端,后端将返回具有有限属性的失败插入,我实际上必须从更大的失败消息中子串来形成数组,但它基本上是这样的:< / p>

var sentRepairs = [
{id: 12345, car: 'Nissan', Model: 'Almera', RepairDate: new Date('2016-04-06'), Modificator: 'User200' },
{id: 12346, car: 'Nissan', Model: 'Almera', RepairDate: new Date('2016-04-07'), Modificator: 'User200' },
{id: 12347, car: 'Toyota', Model: 'Corolla', RepairDate: new Date('2016-04-09'), Modificator: 'User200' },
{id: 12348, car: 'Toyota', Model: 'Corolla', RepairDate: new Date('2016-04-10'), Modificator: 'User200' },
] 

这是我可以从作为字符串的响应行解析的所有数据。

var failedRepairs = [
{ car: 'Toyota', Model: 'Corolla', RepairDate: new Date('2016-04-09'),
{ car: 'Nissan', Model: 'Almera', RepairDate: new Date('2016-04-07')
];

在此之后,我需要制作一个包含修理失败的汽车的子阵列。请注意,同一型号可以进行多次维修。我必须使用的标识符是汽车,型号和日期。后端并没有为我提供身份证明,这将使这一切变得轻而易举。

 var resultsArrayShouldLookLikeThis = [
 {id: 12346, car: 'Nissan', Model: 'Almera', RepairDate: new Date('2016-04-07'), Modificator: 'User200' },
 {id: 12347, car: 'Toyota', Model: 'Corolla', RepairDate: new Date('2016-04-09'), Modificator: 'User200' }
 ]  

正如我意识到这些评论支持这看起来有点糟糕的要求所以这就是我现在所得到的4个未定义的对象作为我预期的结果。如果辅助函数在数组中找到匹配的部分,则返回true,否则返回false。

 var result = sentRepairs.map(function (x) { 
  if (
   helperService.searchArrayByProperty(x.car, failedRepairs, "car") && 
   helperService.searchArrayByProperty(x.Model, failedRepairs, "Model")) {
  return x;
 }
 });

辅助函数本身,它不是由我编写的,我知道它实际上并没有在日期之间进行比较,但即使没有日期比较,我仍然得到4个未定义的对象:

var searchArrayByProperty = function(value, array, property) {
        var item = {};
        var found = false;
        for (var i = 0; i < array.length; i++) {
            if (typeof array[i][property] === "string") {
                if (array[i][property].toString() === value) {
                    item = array[i];
                    found = true;
                }
            }
            else if (typeof array[i][property] === "number") {
                if (array[i][property] === value) {
                    item = array[i];
                    found = true;
                }
            }
            else if (typeof array[i][property] === "boolean") {
                if (array[i][property] === value) {
                    item = array[i];
                    found = true;
                }
            }
            else if (typeof array[i][property] === "undefined") {
                return false;
            }
        }

        if (found) {
            return true;
        } else {
            return false;
        }
    }

4 个答案:

答案 0 :(得分:1)

使用filter和循环:

resultsArrayShouldLookLikeThis  = sentRepairs.filter(function(item){
    for(var i = 0; i < failedRepairs.length; i++){
        if(JSON.stringify(item.RepairDate) == JSON.stringify(failedRepairs[i].RepairDate)){
          return item;
        }
    }
});

我比较了日期,因为它是两个初始数组之间的uniq键。

编辑:https://jsfiddle.net/u39nubpd/1/

我添加了额外的条件

答案 1 :(得分:1)

您可以迭代failedRepairs并构建一个临时对象,该对象在过滤器循环中用于查找。复杂度O(n + m)。

var sentRepairs = [{ id: 12345, car: 'Nissan', Model: 'Almera', RepairDate: new Date('2016-04-06'), Modificator: 'User200' }, { id: 12346, car: 'Nissan', Model: 'Almera', RepairDate: new Date('2016-04-07'), Modificator: 'User200' }, { id: 12347, car: 'Toyota', Model: 'Corolla', RepairDate: new Date('2016-04-09'), Modificator: 'User200' }, { id: 12348, car: 'Toyota', Model: 'Corolla', RepairDate: new Date('2016-04-10'), Modificator: 'User200' }, ],
    failedRepairs = [{ car: 'Toyota', Model: 'Corolla', RepairDate: new Date('2016-04-09') }, { car: 'Nissan', Model: 'Almera', RepairDate: new Date('2016-04-07') }],
    filtered = function (base, faild) {
        function key(o) { return [o.car, o.Model, o.RepairDate].join('|'); }

        var object = {};

        faild.forEach(function (a) {
            object[key(a)] = true;
        });
        return base.filter(function (a) {
            return object[key(a)];
        });
    }(sentRepairs, failedRepairs);

document.write("<pre>" + JSON.stringify(filtered, 0, 4) + "</pre>");

答案 2 :(得分:1)

lodash是为这样的任务制作的实用程序:

var res = _.intersectionWith(sentRepairs,failedRepairs, function(sentItem, failedItem){
        if(sentItem.car == failedItem.car && sentItem.Model && JSON.stringify(sentItem.RepairDate) == JSON.stringify(failedItem.RepairDate)){
       return sentItem;
    }
});

console.log(res);

fiddle

答案 3 :(得分:0)

这是我的解决方案 我可能会以不同的方式解释这个问题,但我认为变量名称可以帮助您理解我的观点。

var initislRequestToBackend = [
{ id: 12345, car: 'Nissan', Model: 'Almera', RepairDate: new Date('2016-04-06'), Modificator: 'User200' },
{ id: 12346, car: 'Nissan', Model: 'Almera', RepairDate: new Date('2016-04-07'), Modificator: 'User200' },
{ id: 12347, car: 'Toyota', Model: 'Corolla', RepairDate: new Date('2016-04-09'), Modificator: 'User200' },
{ id: 12348, car: 'Toyota', Model: 'Corolla', RepairDate: new Date('2016-04-09'), Modificator: 'User200' },
{ id: 12348, car: 'Toyota', Model: 'Corolla', RepairDate: new Date('2016-04-10'), Modificator: 'User200' }];

//

var backendResponse = [{ car: 'Toyota', Model: 'Corolla', RepairDate: new Date('2016-04-09') },
{ car: 'Nissan', Model: 'Almera', RepairDate: new Date('2016-04-07') }];

//

var messageToShow = _.chain(backendResponse)
.reduce(function(output, val) {
    output.push(_.filter(initislRequestToBackend, val));
    return output;
}, [])
.flatten()
.value();
console.log(messageToShow);