试图解决此codwars kata。
给出一个数组,在该数组中找到重复项,然后返回这些重复的新数组。返回的数组的元素首次以重复的方式出现时,应以顺序出现。
示例:
[1, 2, 4, 4, 3, 3, 1, 5, 3, '5'] ==> [4, 3, 1]
[0, 1, 2, 3, 4, 5] ==> []
我有:
function duplicates(arr) {
arr.sort((value, index) => value - index);
let duplicates = [];
for (let i = 0; i < arr.length; i++) {
if (arr[i] === arr[i + 1]) {
duplicates.unshift(arr[i]);
}
}
//filter out duplicates within "duplicates"
duplicates = duplicates.filter((value, index) =>
duplicates.indexOf(value) == index);
return duplicates;
}
console.log(duplicates([1, 2, 4, 4, 3, 1, 5, '5']));
这是通过所有测试,除了一个:
期望:'[1,4]',而是得到:'[4,1]'
我不确定为什么 - 不幸的是,它不会显示测试案例。
建议创建频率映射的另一种方法是在地图上。我该怎么做?
我尝试了:
function duplicates(arr) {
let map = new Map([arr]);
return map;
}
console.log(duplicates([1, 2, 4, 4, 3, 1, 5, '5']));
这不会创建频率图。
您还会有哪些建议?
注意 - " 5"和5不应将其视为相同的值。
编辑 - 最初,尝试创建一个频率图:
function duplicates(arr) {
let map = {};
arr.forEach((value, index) => {
if (!map[value]) {
map[value] = 0;
}
map[value] += 1;
})
return map;
}
console.log(duplicates([1, 2, 4, 4, 3, 1, 5, '5']));
但是,在这种情况下," 5"和5被认为是相同的值。我不知道该如何检查重复项 - 排序会破坏重复项出现的顺序;并创建一个频率图计数数字和字符串作为同一件事。
这是一个应该起作用的想法:
创建一个地图(地图键区分类型,因此5
是与"5"
不同的键(
使用过滤器浏览阵列中的项目。当您仔细考虑您在地图中看到一件项目的次数。仅当计数(在增加计数之前(是1
时,才从过滤器返回true
。那是您第二次看到该项目。
过滤器应返回您的答案:
function duplicates(arr) {
let counts = new Map()
return arr.filter(n => {
let count = counts.get(n)
counts.set(n, count ? count+1 : 1)
return count === 1
})
}
console.log(duplicates([1, 2, 4, 4, 3, 1, 5, '5']));
可能不是最有效的解决方案,但它解决了挑战。请注意,我正在使用JS object
来模仿地图
function duplicates(arr) {
// TODO: return the array of duplicates from arr
const map = {};
const dup = {};
for (const val of arr) {
let key = val;
if (typeof val === 'string') {
key = `${val}_str`;
}
if (map[key]) {
dup[val] = true;
} else {
map[key] = true;
}
}
return Object.keys(dup)
.map( d => (!Number.isInteger(parseInt(d))) ? d : Number(d));
}
console.log(duplicates([1, 2, 4, 4, 3, 1, 5, '5']));