Javascript JS:仅从数组中提取唯一属性对象

Javascript JS:仅从数组中提取唯一属性对象,javascript,Javascript,我目前正在开发一个API,在这里我需要制作一个函数来提取“完全”唯一的对象,即在任何对象中都没有属性匹配 我有一个固定模式的对象数组,如:(修改此) 让arr=[{ “a”:“a1”, “b”:“b1”, “c”:“c1”, “d”:“d1”, “e”:“e1” }, { “a”:“a2”, “b”:“b2”, “c”:“c2”, “d”:“d2”, “e”:“e2” }, { “a”:“a3”, “b”:“b3”, “c”:“c2”,//匹配属性 “d”:“d3”, “e”:“e3” }, /

我目前正在开发一个API,在这里我需要制作一个函数来提取“完全”唯一的对象,即在任何对象中都没有属性匹配

我有一个固定模式的对象数组,如:(修改此)

让arr=[{
“a”:“a1”,
“b”:“b1”,
“c”:“c1”,
“d”:“d1”,
“e”:“e1”
},
{
“a”:“a2”,
“b”:“b2”,
“c”:“c2”,
“d”:“d2”,
“e”:“e2”
},
{
“a”:“a3”,
“b”:“b3”,
“c”:“c2”,//匹配属性
“d”:“d3”,
“e”:“e3”
},
//上一个对象中的值不应影响此唯一对象:
{
“a”:“a3”,
“b”:“b3”,
“c”:“c3”,
“d”:“d3”,
“e”:“e3”
},
//…此处有更多对象,最多200*33个对象
]
我希望结果是:

[
{
“a”:“a1”,
“b”:“b1”,
“c”:“c1”,
“d”:“d1”,
“e”:“e1”
},
{
“a”:“a2”,
“b”:“b2”,
“c”:“c2”,
“d”:“d2”,
“e”:“e2”
},
{
“a”:“a3”,
“b”:“b3”,
“c”:“c3”,
“d”:“d3”,
“e”:“e3”
},
// … 
]
在属性匹配的情况下,数组中首先遇到的对象将被保留,另一个对象将被丢弃。不同的属性永远不会有重叠的值

我当前的实现(错误,请参见备注):


本研究的目的是,本研究的目的是,本研究的目的是,本研究的目的是,本研究的目的是,本研究的目的是,本研究的目的是,本研究的目的是,本研究的目的是,本研究的目的是,本本研究的目的是,本研究的目的是,本研究的目的是,本研究的目的是,本研究的目的是,本研究的目的是,本研究的,以及以及以及其他其他其他其他其他其他的,本研究的,以及以及其他其他其他其他的其他的其他的其他的,本本研究的,以及以及以及其他,本研究的,本研究的,本研究的,本研究的,本研究的研究的研究,以及以及以及以及其他其他,本研究,本研究,本研究,本研究,本研究,本研究,本研究,本研究的研究,本研究,本研究,本研究,本研究,本研究,本研究,本研究,本研究,本研究,本研究,本研究,本研究,本研究,本研究,本研究的(t)——,正确的方法是什么?

我会把目前为止找到的所有值都做一个集合。检查新对象时,请检查其值是否包含在集合中:如果包含,请将其排除,否则将所有值添加到集合中:

让arr=[{
“a”:“a1”,
“b”:“b1”,
“c”:“c1”,
“d”:“d1”,
“e”:“e1”
},
{
“a”:“a2”,
“b”:“b2”,
“c”:“c2”,
“d”:“d2”,
“e”:“e2”
},
{
“a”:“a3”,
“b”:“b3”,
“c”:“c2”,//匹配属性
“d”:“d3”,
“e”:“e3”
},
//上一个对象中的值不应影响此唯一对象:
{
“a”:“a3”,
“b”:“b3”,
“c”:“c3”,
“d”:“d3”,
“e”:“e3”
},
//…此处有更多对象,最多200*33个对象
];
常量值查找=新集合();
const uniques=arr.filter((obj)=>{
常量VAL=对象值(obj);
if(vals.some(val=>valuesFound.has(val))){
返回false;
}
用于(val的常量值){
valuesFound.add(val);
}
返回true;
});

控制台日志(uniques)我认为这更简洁。当某物每次返回false
时,电路就会短路

arr.filter(function(o){
    var that = this,
        vals = Object.values(o),
        pass = vals.every(v=>!~that.indexOf(v));
    return pass && that.push.apply(that,vals);
},[])

将lamba更改为常规func,它可以在任何地方工作,而不仅仅是ES6。

只跟踪值应该比按键查找值更快,尤其是对于每次迭代

下面使用一个全局
缓存
跟踪值,并使用一个本地缓存(即添加的
缓存
)在对象不唯一时提供清理(因此值不会保留在
缓存

const data=getData()
常量缓存={}
const results=data.filter(obj=>{
常量added={}
用于(对象值的常数v(obj)){
if(缓存[v]){
Object.keys(已添加).forEach(v=>删除缓存[v])
返回错误
}
其他的
添加了[v]=缓存[v]=1
}
返回真值
});
控制台日志(结果);
/* ===================================================== */
函数getData(){
返回[{
“a”:“a1”,
“b”:“b1”,
“c”:“c1”,
“d”:“d1”,
“e”:“e1”
},
{
“a”:“a2”,
“b”:“b2”,
“c”:“c2”,
“d”:“d2”,
“e”:“e2”
},
{
“a”:“a3”,
“b”:“b3”,
“c”:“c2”,//匹配属性
“d”:“d3”,
“e”:“e3”
},
//上一个对象中的值不应影响此唯一对象:
{
“a”:“a3”,
“b”:“b3”,
“c”:“c3”,
“d”:“d3”,
“e”:“e3”
},
//…此处有更多对象,最多200*33个对象
];
}
已验证:)


“c”:“d2”
,可能吗?这是一个匹配,在这种情况下,这个重复应该被过滤掉吗?或者不同的属性永远不会有重叠的值吗?@CertainPerformance不同的属性永远不会有重叠的值。在编辑中提到了这一点。@brc dd,因此建议您只需评估values@Mike在您最近发布的答案中,您使用了一个JSON对象
缓存
。在CertainPerformance的回答中,他使用
Set
来存储这些值。你认为哪一个会带来更好的性能?@brc dd我的回答无效,因为它保留了
缓存中的密钥,该密钥丢弃了后续对象。我已经解决了这个问题。为了回答您的问题,我认为
Set
vs object literal的性能有细微差别。这里有一个旧的测试(),它可以更快地显示对象文本。我想节点已经被优化了,正如注释所示,它依赖于被捕获的值。出于习惯和偏好,我使用对象文字(我发现它更容易阅读)
arr.filter(function(o){
    var that = this,
        vals = Object.values(o),
        pass = vals.every(v=>!~that.indexOf(v));
    return pass && that.push.apply(that,vals);
},[])
     let ids=[]
     let filtered_arr=arr.filter(ar=>{
      if(ids.includes(ar.c)){ 
        return false
       }    
       else{
        ids.push(ar.c);
        return true;}  
     }  
      )
    console.log(filtered_arr);