Javascript JS:仅从数组中提取唯一属性对象
我目前正在开发一个API,在这里我需要制作一个函数来提取“完全”唯一的对象,即在任何对象中都没有属性匹配 我有一个固定模式的对象数组,如:(修改此)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” }, /
让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);