删除 Javascript 中对象中具有相同值(即重复)的 key/value 对

Remove key/value pairs with the same value (i.e. duplicates) in an object in Javascript

我目前正在学习 JS,我需要一种方法来 return 一个与给定对象相似的对象,但删除 key/value 具有相同值(即重复项)的对。

所以如果我有一个给定的对象 { a: 1, b: 2, c: 3, d: 1 }:

应该return:

{b:2,c:3}

类似地,如果对象中的所有键值对都有不同的值,returned 对象将与给定对象完全相同。

我想我快要解决它了,但我无法弄清楚我的代码有什么问题。任何帮助将不胜感激!

const noDuplicateValues = (obj) => {
  let result = {};
  let keys = Object.keys(obj);
  let duplicate;

  for(let i = 0; i < keys.length; i++) {
    for(let j = i +1; j < keys.length; j++) {
      duplicate = false;
      if(obj[keys[i]] === obj[keys[j]]) {
        duplicate = true;
      }
    }
    if(!duplicate) {
      result[keys[i]] = obj[keys[i]];
    } 
  }
  return result;
}

我会计算每个值出现的次数,然后根据给定条目的值是否只出现一次来过滤对象的条目:

const obj = { a: 1, b: 2, c: 3, d: 1 };
const occurrences = new Map();
for (const val of Object.values(obj)) {
  occurrences.set(val, (occurrences.get(val) || 0) + 1);
}
const newObj = Object.fromEntries(
  Object.entries(obj)
    .filter(([, val]) => occurrences.get(val) === 1)
);
console.log(newObj);

为了加快速度,您的内部循环可以在发现重复项后立即退出。但是阻止它正常工作的缺陷是,虽然它发现 ad 的副本并正确地省略了 a,但它并没有省略 d 因为当它检查 d,这是数组中的最后一个元素时,没有后续元素可供比较,因此它不认为 d 是重复的。

修复是让内循环检查每个元素(不仅仅是外循环检查的元素之后的元素),当然要注意不要检查一个针对自身的元素:

const noDuplicateValues = (obj) => {
    let result = {};
    let keys = Object.keys(obj);
    let duplicate;

    for (let i = 0; i < keys.length; i++) {
        duplicate = false;
        for (let j = 0; j < keys.length; j++) {
            if (
                i !== j // Don't compare an element with itself
                &&
                obj[keys[i]] === obj[keys[j]]
            ) {
                duplicate = true;
                break; // Found a dupe so we can stop checking this one for dupes
            }
        }
        if (!duplicate) {
            result[keys[i]] = obj[keys[i]];
        }
    }
    return result;
}

var x = noDuplicateValues({ a: 1, b: 2, c: 3, d: 1 });
console.log(x); // Object { b: 2, c: 3 }

您的代码有两个问题。 第一个是 duplicate 的值在内循环中设置为 false ,应该在外循环中设置。 第二个问题是内循环只从 i + 1 开始。因此它实际上做了以下比较:

  • a 对比 ba 对比 ca 对比 d
  • b 对比 cb 对比 d
  • c 对比 d

所以您还需要比较 dabc 的值。所以像这样的东西应该有用。

const noDuplicateValues = (obj) => {
  let result = {};
  let keys = Object.keys(obj);
  let duplicate;

  for(let i = 0; i < keys.length; i++) { 
    duplicate = false;
    for(let j = 0; j < keys.length; j++) {
      
      if(i !== j && obj[keys[i]] === obj[keys[j]]) {
        duplicate = true;
      }
    }
    if(!duplicate) {
      result[keys[i]] = obj[keys[i]];
    } 
  }
  return result;
}

但是,如果您只跟踪值和出现次数,效率会更高:1:出现 2 次,2:1 次,3:1 次 ... 然后你可以删除所有值出现超过 1 次的 key-value 对。这样你只需要遍历所有属性一次。