在JavaScript中处理数组时,有时我们想确定该数组是否包含任何重复值。不幸的是,JavaScript数组没有任何内置方法可以为我们做到这一点,我们必须自己编写实现。
解决此问题一种方法如下所示:
function checkForDuplicates(array) {
let valuesAlreadySeen = []
for (let i = 0; i < array.length; i++) {
let value = array[i]
if (valuesAlreadySeen.indexOf(value) !== -1) {
return true
}
valuesAlreadySeen.push(value)
}
return false
}
这种方式是可行的,但是在最坏的情况下,也就是重复值出现在数组的末尾,我们将不得不遍历整个数组(O(n)这n可能是巨大的!),只有遍历到在最后一个元素上,数组中才存在一个非唯一值。这不是一种非常有效的方法。
另一种方法利用了ES6 Set的功能。
如果您不熟悉JavaScript中的Set,这是MDN定义:
Set对象是值的集合。您可以按插入顺序遍历集合的元素。集合中的值只能出现一次;它在Set的集合中是唯一的。
根据这个特点意味着我们可以将原始数组转换为Set,然后它仅包含唯一值。一旦从数组中提取了所有唯一值并将它们存储在Set中,我们就可以比较数组和Set的长度。如果长度不同,则说明该数组包含重复值!
这种方法如下所示:
function checkForDuplicates(array) {
return new Set(array).size !== array.length
}
如果Set的长度与数组的长度不同,则此函数将返回true,表示数组确实包含重复项。否则,如果数组和Set的长度相同,则该函数将返回false,我们可以确定原始数组中没有重复的值!
其实Set这种数据结构非常适合求数组的交集,并集,差集。
交集
function insertion (a, b) {
a = new Set(a);
b = new Set(b);
[...a].filter(item => {
return b.has(item) // 有包含关系
})
}
并集
let a = [1, 2, 3]
let b = [3, 4, 5]
function union (a, b) {
let newArr = [...new Set([...a, ...b])]
return newArr
}
union(a, b)
差集
function difference (a, b) {
a = new Set(a);
b = new Set(b);
[...a].filter(item => {
return !b.has(item) // 没有包含关系
})
}