如何解决删除Javascript对象中具有相同值即重复项的键/值对
我目前正在学习JS,我需要一种方法来返回与给定对象相似的对象,但要删除具有相同值(即重复项)的键/值对。
因此,如果我有给定的对象{a:1,b:2,c:3,d:1}:
它应该返回:
{b:2,c:3}
类似地,如果一个对象中的所有键值对都具有不同的值,则返回的对象将与给定对象完全相同。
我认为我即将解决它,但是我无法弄清楚我的代码有什么问题。任何帮助将不胜感激!
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,d: 1 });
console.log(x); // Object { b: 2,c: 3 }
,
您的代码有两个问题。
第一个是将duplicate
的值在内部循环中设置为false
,而应在外部循环中将其设置。
第二个问题是内部循环仅从i + 1
开始。因此,它实际上进行了以下比较:
-
a
vsb
,a
vsc
,a
vsd
-
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次以上的所有键值对。这样,您只需要遍历所有属性一次。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。