在JavaScript对象数组中查找某些键的重复项,并将相关键设置为true

在JavaScript对象数组中查找某些键的重复项,并将相关键设置为true,javascript,duplicates,Javascript,Duplicates,我有一个JS对象数组: var a = [{a:"a1",b:"b",c:"c",prop:false}, {a:"a1",b:"b",c:"c",prop:false}, {a:"a",b:"b",c:"c",prop:false}, {a:"a2",b:"b",c:"c",prop:false}, {a:"a3",b:"b",c:"c",prop:false}, {a:"a1",

我有一个JS对象数组:

  var a = [{a:"a1",b:"b",c:"c",prop:false},
           {a:"a1",b:"b",c:"c",prop:false},
           {a:"a",b:"b",c:"c",prop:false},
           {a:"a2",b:"b",c:"c",prop:false},
           {a:"a3",b:"b",c:"c",prop:false},
           {a:"a1",b:"b",c:"c",prop:false}];
我必须找到最后一个元素的副本,但不考虑键
prop
:当我找到它们时,相关的prop布尔值必须设置为
true

我做了世界上最简单的事情,效果很好,但我想知道JS是否可以做一些更好的事情(没有第三方库),无论是“优雅”、现代还是性能:

var toTest = a[a.length-1];
for(var i=0;i<a.length;i++){
      if(toTest.a==a[i].a && toTest.b==a[i].b && toTest.c==a[i].c){
         a[i].prop = true;
         a[a.length-1].prop = true;
      }
    }
var-toTest=a[a.length-1];
对于(var i=0;i使用
Array.filter()
和只比较
a
b
c
的函数


编辑:我完全替换了我以前的答案。我认为Array.filter()是一种搜索数组中最后一个条目的重复项的方法。

你所拥有的几乎就是它。你可以做一些调整,但它与一样好,除了当
I
(因为您不希望将最后一个条目与自身进行比较,并错误地设置
prop

您可以做一些调整:

  • a[a.length-1].prop=true;
    可以是
    toTest.prop=true;
  • 您可以将
    a[i]
    缓存到变量,而不是每次都查找它
  • 您可以缓存
    a
    b
    c
    ,而不是每次都在对象上查找它们(但JavaScript引擎会在重要的情况下这样做)
  • 在ES2015+中,您可以使用解构分配来获取
    a
    b
    c
例如:

// Caching the last item
var last = a[a.length - 1];
// Caching the values to check
var checka = last.a, checkb = last.b, checkc = last.c;
// Stop at i < a.length - 1, caching that to l
for (var i = 0, l = a.length - 1; i < l; ++i) {
    // Cache a[i]
    var entry = a[i];
    if (entry.a == checka && entry.b == checkb && entry.c == checkc) {
        entry.prop = last.prop = true;
    }
}

您可以组合使用
Array.forEach
Array.every
。创建要测试的键列表,并在每次迭代中检查这些键并更新对象

a[a.length-1].prop=true
对我来说似乎没有必要,因为您没有删除该项,因此它将在上一次迭代中更新

var a=[{a:a1],b:b,c:c,prop:false},
{a:“a1”,b:“b”,c:“c”,prop:false},
{a:“a”,b:“b”,c:“c”,prop:false},
{a:“a2”,b:“b”,c:“c”,prop:false},
{a:“a3”,b:“b”,c:“c”,prop:false},
{a:“a1”,b:“b”,c:“c”,prop:false}];
var toTest=a[a.长度-1];
var-keystest=['a','b','c'];
a、 forEach((o)=>{
var valid=keystest.every((k)=>o[k]==toTest[k]);
如果(有效){
o、 prop=真;
}
});

console.log(a)
您可以使用普通的
forEach
循环

var a=[{a:“a1”、b:“b”、c:“c”、prop:false}、{a:“a1”、b:“b”、c:“c”、prop:false}、{a:“a2”、b:“b”、c:“c”、prop:false}、{a:“a1”、b:“b”、c:“c”、prop:false}、{a:“a1”、b:“b:“c”、prop:false};
var toTest=a[a.长度-1];
a、 forEach(功能(项目){
item.prop=(item.a==toTest.a&&item.b==toTest.b&&item.c==toTest.c)?真:假;
});

控制台日志(a);
@meowgoestedog什么是JS中的字典?你是指对象还是映射?你可以为b和c创建一个聚合键并将它们放入哈希,然后在遍历数组时只需检查哈希中是否已有条目。你能使用es6吗?@Logar:是的,我可以can@neuhaus:如果你愿意,你可以发布i作为解决方案i不看看生成大量临时字符串和执行大量不必要的字符串串联是如何比使用
&&
有所改进的。好吧,我有点误解了这个问题,我认为他必须找到数组中的所有重复项。如果你只想检查一个值,最好以你建议的简单方式对其进行迭代。我不会错请回答,但如果OP“必须找到最后一个元素的副本,但不考虑关键道具”,如果我们循环对象属性而不是手动列出它们,不是更好吗?@3000:我已经更新为包含ES5和更早版本version@Logar:如果属性是可变的,当然,我们会提前得到列表。从OP的代码中,我感觉它们是静态的。哇,非常紧凑