.filter()来自不同来源的相同数据

时间:2018-06-01 14:13:16

标签: javascript react-native

我有2个阵列:

var yin =  [{"_id": "11111", "name": "blue"}];
var yang = [{"_id": "11111", "name": "blue"}, {"_id": "22222", "name": "red"}];

我尝试过滤掉以下内容:

var yang = yang.filter(function(e){ return this.indexOf(e) < 0; }, yin);

出于某种原因,indexOf(e)正在返回-1,我知道它是完全相同的数据。我唯一能想到的是有一些关系(可能不是正确的术语)数据位于下面,这使得它们看起来不一样,因为对象来自完全不同的数据库源。

是否有另一种方法可以从来自不同来源的对象数组中过滤出相同的数据?

我知道这个过滤器功能有效,因为如果我使用.push()推送数据,它会过滤掉就好了。

5 个答案:

答案 0 :(得分:1)

问题在于它们没有相同的对象。

他们的对象看起来相同。

举个简单的例子,看一下:

console.log({} == {});
console.log({} === {});

请注意,即使这些对象看起来完全相同,它们也不相同。与原语(字符串,数字)不同,对象彼此都是唯一的。

您需要做的是实现自己的contains()函数,该函数将对对象中的每个属性进行比较:

const yin =  [{"_id": "11111", "name": "blue"}];
const yang = [{"_id": "11111", "name": "blue"}, {"_id": "22222", "name": "red"}];

function contains(arr, el) {
  return arr.some(i => equal(i, el));
}

function equal(a, b) {
  return Object.keys(a).length === Object.keys(b).length
    && Object.entries(a).every(([key, val]) => a[key] === b[key]);
}

// or !contains() if you want the difference
const result = yang.filter(function(el) { return contains(this, el) }, yin);

console.log(result);

equal()函数只进行浅层比较。如果对象更复杂,那么你会想要一些深层次的东西,并通过所有元素进行递归。幸运的是,在许多流行的库和独立的Node模块中已经实现了很多选项,因此您不必自己实现它。

答案 1 :(得分:1)

问题在于,你的意思是两个不同的对象永远不会相等。您需要对对象进行深入比较(手动),或者如果它符合您的需求,您可以检查相等的_id属性。

&#13;
&#13;
var yin =  [{"_id": "11111", "name": "blue"}];
var yang = [{"_id": "11111", "name": "blue"}, {"_id": "22222", "name": "red"}];

yang = yang.filter(function(e){ 
return this.findIndex(function(y){return y._id === e._id}) < 0; }, yin);

console.log(yang);
&#13;
&#13;
&#13;

答案 2 :(得分:0)

问题:

var yin =  [{"_id": "11111", "name": "blue"}];
yin.indexOf({"_id": "11111", "name": "blue"}) // return -1

因此,我建议使用新功能来过滤您需要的字段。

使用箭头功能:

yang.filter( e => yin.some(a => (a._id == e._id && a.name == e.name)));

没有箭头功能:

yang.filter( function(elementYang) {
    return yin.some(function(elementYing) {
        return (elementYang._id == elementYing._id) && (elementYang._name == elementYing._name);
    });
});

答案 3 :(得分:0)

这会奏效。

var new = yang.filter((yang) => {
    for (let i = 0; i < yin.length; i++) {
      if (yin[i]._id==yang._id) {
        return yang;
      }
    }
  });

答案 4 :(得分:0)

您需要使用sam对象引用来比较对象。

var object = { _id: "11111", name: "blue" },
    yin =  [object],
    yang = [object, { _id: "22222", name: "red" }];

yang = yang.filter(function(e){ return this.indexOf(e) < 0; }, yin);

console.log(yang)

通过分配对象的相同键,无需对象引用。

var yin =  [{ _id: "11111", name: "blue" }],
    yang = [{ _id: "11111", name: "blue" }, { _id: "22222", name: "red" }];

yang = yang.filter(o => !yin.some(p => Object.keys(o).every(k => o[k] === p[k])));

console.log(yang);