删除 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);
为了加快速度,您的内部循环可以在发现重复项后立即退出。但是阻止它正常工作的缺陷是,虽然它发现 a
是 d
的副本并正确地省略了 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
对比 b
、a
对比 c
、a
对比 d
b
对比 c
、b
对比 d
c
对比 d
所以您还需要比较 d
与 a
、b
、c
的值。所以像这样的东西应该有用。
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 对。这样你只需要遍历所有属性一次。
我目前正在学习 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);
为了加快速度,您的内部循环可以在发现重复项后立即退出。但是阻止它正常工作的缺陷是,虽然它发现 a
是 d
的副本并正确地省略了 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
对比b
、a
对比c
、a
对比d
b
对比c
、b
对比d
c
对比d
所以您还需要比较 d
与 a
、b
、c
的值。所以像这样的东西应该有用。
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 对。这样你只需要遍历所有属性一次。