Talk is cheap,Show you the code.
var fruits=['苹果','香蕉','葡萄','火龙果','苹果','葡萄','火龙果']
distinct(fruits);
console.log(fruits);
//(4) ["苹果", "香蕉", "葡萄", "火龙果"]
//双重循环
function distinct(arr) {
for (let i=0, len=arr.length; i<len; i++) {
for (let j=i+1; j<len; j++) {
if (arr[i] == arr[j]) {
arr.splice(j, 1);
// splice 会改变数组长度,所以要将数组长度 len 和下标 j 减一
len--;
j--;
}
}
}
return arr;
}
这种方式的去重简单来说就是我从第一个开始循环剩下的与之对比,去掉相同的所以这个的方式它的时间复杂度是O(n^2),如果数组长度很大,效率会很低,另外如果数组中有NAN的话也是无法去重的。(NaN==NaN为false)
如果数组里面是对象,我们知道每个对象都会开辟一个新的空间,所以在判断相等时内容一样,也不会一样,所以在构造数据时,我们可以在里面放一个唯一标识,一般后端给我妈传回来的数据应该都有一个id。
var student=[
{
id:1,
name:'zs'
},
{
id:2,
name:'ls'
},
{
id:3,
name:'we'
},
{
id:3,
name:'we'
},
{
id:1,
name:'zs'
},
]
distinct(student);
console.log(student);
// 0: {id: 1, name: "zs"}
// 1: {id: 2, name: "ls"}
// 2: {id: 3, name: "we"}
// length: 3
function distinct(arr) {
for (let i=0, len=arr.length; i<len; i++) {
for (let j=i+1; j<len; j++) {
if (arr[i].id == arr[j].id) {
arr.splice(j, 1);
// splice 会改变数组长度,所以要将数组长度 len 和下标 j 减一
len--;
j--;
}
}
}
return arr;
}
var fruits=['苹果','香蕉','葡萄','火龙果','苹果','葡萄','火龙果']
var fruits1Two=['苹果','牛油果','桃子','菠萝','桃子']
console.log(distinct(fruits,fruits1Two));
//(7) ["苹果", "香蕉", "葡萄", "火龙果", "牛油果", "桃子", "菠萝"]
//Array.filter() 加 indexOf
function distinct3(a, b) {
let arr = a.concat(b);
return arr.filter((item, index)=> {
return arr.indexOf(item) === index
})
}
利用indexOf检测元素在数组中第一次出现的位置是否和元素现在的位置相等,如果不等则说明该元素是重复元素。此方法对象不去重,NaN会被忽落掉(arr.indexOf(Nan)=-1)。
var fruits=['苹果','香蕉','葡萄','火龙果','苹果','葡萄','火龙果']
console.log(distinct(fruits));
// ["火龙果", "苹果", "葡萄", "香蕉"]
function distinct(array) {
var res = [];
var sortedArray = array.concat().sort();
var seen;
for (var i = 0, len = sortedArray.length; i < len; i++) {
// 如果是第一个元素或者相邻的元素不相同
if (!i || seen !== sortedArray[i]) {
res.push(sortedArray[i])
}
seen = sortedArray[i];
}
return res;
}
先调用数组的排序方法,然后比较相邻的两个是否相等从而实现去重。此方法对象和NaN不去重,数字1与字符串1也不去重。
注:V8引擎 的 sort() 方法在数组长度小于等于10的情况下,会使用插入排序,大于10的情况下会使用快速排序
var fruits=['苹果','香蕉','葡萄','火龙果','苹果','葡萄','火龙果']
console.log(distinct(fruits));
// ["苹果", "香蕉", "葡萄", "火龙果"]
function distinct(array) {
return Array.from(new Set(array));
}
可以简化为:
function distinct(array) {
return [...new Set(array)];
}
甚至:
let distinct = (a) => [...new Set(a)]
Es6提供的Set 结构的一个特性就是成员值都是唯一的,没有重复的值,此方法对象不去重,NaN去重。
function distinct(array) {
var obj = {};
return array.filter(function(item, index, array){
return obj.hasOwnProperty(typeof item + item) ? false : (obj[typeof item + item] = true)
})
}
这种方法是利用一个空的 Object 对象,我们把数组的值存成 Object 的 key 值,比如 Object[value1] = true,在判断另一个值的时候,如果 Object[value2]存在的话,就说明该值是重复的,但是最后请注意这里obj[typeof item + item] = true没有直接使用obj[item],是因为 123 和 ‘123’ 是不同的,直接使用前面的方法会判断为同一个值,因为对象的键值只能是字符串,所以我们可以使用 typeof item + item 拼成字符串作为 key 值来避免这个问题。此方法对象、NaN均去重。
参考:https://mp.weixin.qq.com/s/T_HZEqlUqqtufBPtg3eWvA