使用jQuery或JavaScript过滤数组中的另一个数组

3
我想要筛选一个名为 'arrSOPrecods' 的数组,按照来自 'outputdata' 另一个数组的关键值进行筛选。第一个数组 'arrSOPrecods' 包含了需要训练特定 SOP 的用户记录;第二个数组 'outputdata' 则包含了已经接受了特定 SOP 训练的用户记录。我需要从 arrSOprecords 中筛选出在 outputdata 中已存在的记录。我已经尝试了很多不同的方法,比如 jQuery filter、JavaScript for loop 以及其自带的 .filter 函数,但进展甚微,没有什么有用的结果。下面是数据示例以及最终输出结果应该是什么。
var arrSOPrecords = [
    { User: "Cesar", SOP: "training 1" },
    { User: "Cesar", SOP: "training 2" },
    { User: "Jon", SOP: "training 1" },
    { User: "Jon", SOP: "training 2" },
    { User: "Ana", SOP: "training 1" },
    { User: "Ana", SOP: "training 2" }
];

var outputdata = [
    { User: "Cesar", SOP: "training 1" }, 
    { User: "Cesar", SOP: "training 2" }, 
    { User: "Ana", SOP: "training 1" }, 
    { User: "Jon", SOP: "training 1" }
];

最终输出数组。
var filtered = [
    { User: "Ana", SOP: "training 2" },
    { User: "Jon", SOP: "training 2" }
];
6个回答

4

您可以使用哈希表来排除和过滤记录中的项目。

var arrSOPrecords = [{ User: "Cesar", SOP: "training 1" }, { User: "Cesar", SOP: "training 2" }, { User: "Jon", SOP: "training 1" }, { User: "Jon", SOP: "training 2" }, { User: "Ana", SOP: "training 1" }, { User: "Ana", SOP: "training 2" }],
    outputdata = [{ User: "Cesar", SOP: "training 1" }, { User: "Cesar", SOP: "training 2" }, { User: "Ana", SOP: "training 1" }, { User: "Jon", SOP: "training 1" }],
    filtered,
    hash = Object.create(null);

outputdata.forEach(function (a) {
    hash[a.User + '|' + a.SOP] = true;
});
filtered = arrSOPrecords.filter(function (a) {
    return !hash[a.User + '|' + a.SOP];
});

console.log(filtered);


1
你可以在两个数组上使用map(),返回User + SOP的字符串,然后使用indexOf()进行过滤。

var arrSOPrecords=[{User:"Cesar", SOP:"training 1"},{User:"Cesar", SOP:"training 2"},{User:"Jon", SOP:"training 1"},{User:"Jon", SOP:"training 2"},{User:"Ana", SOP:"training 1"},{User:"Ana", SOP:"training 2"}]; 
var outputdata= [{User:"Cesar", SOP:"training 1"},{User:"Cesar", SOP:"training 2"},{User:"Ana", SOP:"training 1"},{User:"Jon", SOP:"training 1"}]

var a = arrSOPrecords.map(e => e.User+e.SOP);
var b = outputdata.map(e => e.User+e.SOP);

var result = arrSOPrecords.filter(function(e, i) {
  return b.indexOf(a[i]) == -1;
});

console.log(result)

更新: 你实际上可以在第二个数组上使用map,然后像这样使用filter

var arrSOPrecords = [{ User: "Cesar", SOP: "training 1" }, { User: "Cesar", SOP: "training 2" }, { User: "Jon", SOP: "training 1" }, { User: "Jon", SOP: "training 2" }, { User: "Ana", SOP: "training 1" }, { User: "Ana", SOP: "training 2" }];
var outputdata = [{ User: "Cesar", SOP: "training 1" }, { User: "Cesar", SOP: "training 2" }, { User: "Ana", SOP: "training 1" }, { User: "Jon", SOP: "training 1" }];

var a = outputdata.map(e => e.User+e.SOP);
var result = arrSOPrecords.filter(function(el) {
  return a.indexOf(el.User+el.SOP) == -1;
})

console.log(result)


我尝试了几个建议,这一个似乎是最有效的,感谢大家提供的所有建议,你们都很棒,我非常感激。 - user3667159

1

Array.prototype.filter() + Array.prototype.some()

这段文本是关于编程的内容,讨论了两个数组方法:filter()和some()。请注意保留html标签,不要进行解释。

var arrSOPrecords = [
    { User: "Cesar", SOP: "training 1" },
    { User: "Cesar", SOP: "training 2" },
    { User: "Jon", SOP: "training 1" },
    { User: "Jon", SOP: "training 2" },
    { User: "Ana", SOP: "training 1" },
    { User: "Ana", SOP: "training 2" }
];

var outputdata = [
    { User: "Cesar", SOP: "training 1" }, 
    { User: "Cesar", SOP: "training 2" }, 
    { User: "Ana", SOP: "training 1" }, 
    { User: "Jon", SOP: "training 1" }
];

var filtered = arrSOPrecords.filter(function(r) {
    return !outputdata.some(function(t) {
        return r.User === t.User && r.SOP === t.SOP;
    });
});

console.log(JSON.stringify(filtered));


0

你可以尝试使用array.some方法过滤第一个数组:

var arrSOPrecords=[{User:"Cesar", SOP:"training 1"},{User:"Cesar", SOP:"training 2"},{User:"Jon", SOP:"training 1"},{User:"Jon", SOP:"training 2"},{User:"Ana", SOP:"training 1"},{User:"Ana", SOP:"training 2"}];
var outputdata= [{User:"Cesar", SOP:"training 1"},{User:"Cesar", SOP:"training 2"},{User:"Ana", SOP:"training 1"},{User:"Jon", SOP:"training 1"}]


var r = arrSOPrecords.filter(x => !outputdata.some(y => _.isEqual(y,x)))

console.log(r)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.min.js"></script>

为了比较some方法内的对象,我使用了lodash的isEqual方法,但你也可以使用其他方法来测试对象。


0

我喜欢提供通用的、可重复使用的解决方案来解决这些问题。以下代码将列出在调用的数组中存在但在作为参数提供的数组中缺失的对象。我们利用了两个通用方法:Object.prototype.compare()Array.prototype.diference()

Object.prototype.compare = function(o){
  var ok = Object.keys(this);
  return typeof o === "object" && ok.length === Object.keys(o).length ? ok.every(k => this[k] === o[k]) : false;
};
Array.prototype.difference = function(a) {
  return this.filter(e => !a.some(f => f.compare(e)));
};
var arrSOP = [
    { User: "Cesar", SOP: "training 1" },
    { User: "Cesar", SOP: "training 2" },
    { User: "Jon", SOP: "training 1" },
    { User: "Jon", SOP: "training 2" },
    { User: "Ana", SOP: "training 1" },
    { User: "Ana", SOP: "training 2" }
],
   outData = [
    { User: "Cesar", SOP: "training 1" }, 
    { User: "Cesar", SOP: "training 2" }, 
    { User: "Ana", SOP: "training 1" }, 
    { User: "Jon", SOP: "training 1" }
],
  filtered = arrSOP.difference(outData);
console.log(JSON.stringify(filtered));


0

这里有一个简单的解决方案,使用Array.filterArray.indexOf函数:

var filtered = [], trained = {};

outputdata.forEach(function(o) {
    trained[o.User] = trained[o.User] || [];
    trained[o.User].push(o.SOP);
});
filtered = arrSOPrecords.filter(function(o) {
    return !trained[o.User] || trained[o.User].indexOf(o.SOP) === -1;
});

console.log(JSON.stringify(filtered, 0 , 4)); 

输出:

[
    {
        "User": "Jon",
        "SOP": "training 2"
    },
    {
        "User": "Ana",
        "SOP": "training 2"
    }
]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接