Javascript 从JS数组中删除重复值

Javascript 从JS数组中删除重复值,javascript,arrays,duplicates,unique,Javascript,Arrays,Duplicates,Unique,我有一个非常简单的JavaScript数组,它可能包含也可能不包含重复项 var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"]; 我需要删除重复项并将唯一值放入新数组中 我可以指出我尝试过的所有代码,但我认为这是无用的,因为它们不起作用。我也接受jQuery解决方案 类似问题: 香草JS:使用类似集合的对象删除重复项 var x=[1,2,3,3,2,1]; x.unique() //[1,2,3] var a

我有一个非常简单的JavaScript数组,它可能包含也可能不包含重复项

var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];
我需要删除重复项并将唯一值放入新数组中

我可以指出我尝试过的所有代码,但我认为这是无用的,因为它们不起作用。我也接受jQuery解决方案

类似问题:

香草JS:使用类似集合的对象删除重复项

var x=[1,2,3,3,2,1];
x.unique() //[1,2,3]
var a = [2,3,4,5,5,4];
a.filter(function(value, index){ return a.indexOf(value) == index });
您始终可以尝试将其放入对象中,然后遍历其键:

function remove_duplicates(arr) {
    var obj = {};
    var ret_arr = [];
    for (var i = 0; i < arr.length; i++) {
        obj[arr[i]] = true;
    }
    for (var key in obj) {
        ret_arr.push(key);
    }
    return ret_arr;
}
用法示例:

a = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];

b = remove_duplicates(a);
// b:
// ["Adam", "Carl", "Jenny", "Matt", "Mike", "Nancy"]

c = remove_duplicates_safe(a);
// c:
// ["Mike", "Matt", "Nancy", "Adam", "Jenny", "Carl"]

d = remove_duplicates_es6(a);
// d:
// ["Mike", "Matt", "Nancy", "Adam", "Jenny", "Carl"]
TL;博士 使用构造函数和


“聪明”但天真的方式 基本上,我们迭代数组,对于每个元素,检查数组中该元素的第一个位置是否等于当前位置。显然,对于重复元素,这两个位置是不同的

使用过滤器回调的第3个(“this array”)参数,我们可以避免数组变量关闭:

uniqueArray = a.filter(function(item, pos, self) {
    return self.indexOf(item) == pos;
})
虽然简洁,但该算法对于大型阵列(二次时间)不是特别有效

哈希表的解救 通常是这样做的。其思想是将每个元素放在哈希表中,然后立即检查其存在性。这给了我们线性时间,但至少有两个缺点:

  • 由于哈希键在JavaScript中只能是字符串或符号,因此此代码不区分数字和“数字字符串”。也就是说,
    uniq([1,“1”])
    将只返回
    [1]
  • 出于同样的原因,所有对象都将被视为相等:
    uniq([{foo:1},{foo:2}])
    将只返回
    [{foo:1}]
也就是说,如果您的数组只包含原语,而不关心类型(例如,它总是数字),那么此解决方案是最优的

来自两个世界的最好 通用解决方案结合了这两种方法:它使用散列查找原语和线性搜索对象

function uniq(a) {
    var prims = {"boolean":{}, "number":{}, "string":{}}, objs = [];

    return a.filter(function(item) {
        var type = typeof item;
        if(type in prims)
            return prims[type].hasOwnProperty(item) ? false : (prims[type][item] = true);
        else
            return objs.indexOf(item) >= 0 ? false : objs.push(item);
    });
}
排序| uniq 另一个选项是先对数组排序,然后删除与前一个元素相等的每个元素:

function uniq(a) {
    return a.sort().filter(function(item, pos, ary) {
        return !pos || item != ary[pos - 1];
    });
}
同样,这不适用于对象(因为对于
排序
,所有对象都是相等的)。此外,我们悄悄地更改原始阵列作为副作用-不好!但是,如果您的输入已经排序,这就是方法(只需从上面删除
sort

独一无二的。。。 有时,我们希望根据一些标准(而不仅仅是相等)对列表进行唯一化,例如,筛选出不同但共享某些属性的对象。这可以通过传递回调优雅地完成。此“键”回调应用于每个元素,并删除具有相等“键”的元素。由于
预计将返回原语,因此哈希表在这里可以正常工作:

function uniqBy(a, key) {
    var seen = {};
    return a.filter(function(item) {
        var k = key(item);
        return seen.hasOwnProperty(k) ? false : (seen[k] = true);
    })
}
一个特别有用的
key()
JSON.stringify
,它将删除物理上不同但“外观”相同的对象:

a = [[1,2,3], [4,5,6], [1,2,3]]
b = uniqBy(a, JSON.stringify)
console.log(b) // [[1,2,3], [4,5,6]]
如果
不是原语,则必须使用线性搜索:

function uniqBy(a, key) {
    var index = [];
    return a.filter(function (item) {
        var k = key(item);
        return index.indexOf(k) >= 0 ? false : index.push(k);
    });
}
在ES6中,您可以使用
集合

function uniqBy(a, key) {
    let seen = new Set();
    return a.filter(item => {
        let k = key(item);
        return seen.has(k) ? false : seen.add(k);
    });
}
地图

function uniqBy(a, key) {
    return [
        ...new Map(
            a.map(x => [key(x), x])
        ).values()
    ]
}
这两种方法也适用于非基本键

第一个还是最后一个? 通过键删除对象时,可能希望保持第一个或最后一个“相等”对象

使用上面的
设置
变量保留第一个,使用
映射
保留最后一个:

函数uniqByKeepFirst(a,键){
let seen=新集合();
返回a.filter(项=>{
设k=键(项);
返回seen.has(k)?false:seen.add(k);
});
}
函数uniqByKeepLast(a,键){
返回[
…新地图(
a、 映射(x=>[键(x),x])
).values()
]
}
//
数据=[
{a:1,u:1},
{a:2,u:2},
{a:3,u:3},
{a:4,u:1},
{a:5,u:2},
{a:6,u:3},
];
log(uniqByKeepFirst(data,it=>it.u))

log(uniqByKeepLast(data,it=>it.u))
使用jQuery快速且不干净:

var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];
var uniqueNames = [];
$.each(names, function(i, el){
    if($.inArray(el, uniqueNames) === -1) uniqueNames.push(el);
});
使用 它是一个库,包含许多用于操纵数组的函数

这是与jQuery的tux和Backbone.js搭配的纽带 吊带

var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];

alert(_.uniq(names, false));
\uuq.uniq(数组,[isSorted],[iterator])
别名:唯一
使用===来测试对象,生成数组的重复免费版本 平等。如果您事先知道数组已排序,则传递 对于为true,排序后的将运行更快的算法。如果你想 基于转换计算唯一项,传递一个迭代器 功能

var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];

alert(_.uniq(names, false));

注:(竞争对手)也提供了类似的实现。

以下内容比列出的jQuery方法快80%以上(参见下面的测试)。 这是几年前一个类似问题的答案。如果我遇到最初提出这个建议的人,我会贴信用卡。 纯JS

var-temp={};
对于(var i=0;i
我的测试用例比较:

最重要的答案的复杂性为
O(n²)
,但这可以通过使用对象作为散列来实现:

function getDistinctArray(arr) {
    var dups = {};
    return arr.filter(function(el) {
        var hash = el.valueOf();
        var isDup = dups[hash];
        dups[hash] = true;
        return !isDup;
    });
}
这适用于字符串、数字和日期。如果数组包含对象,则上述解决方案将不起作用,因为当强制为字符串时,它们的值都将为
“[object object]”
(或类似值),而这不适合用作查找值。您可以通过在对象本身上设置标志来获得对象的
O(n)
实现:

function getDistinctObjArray(arr) {
    var distinctArr = arr.filter(function(el) {
        var isDup = el.inArray;
        el.inArray = true;
        return !isDup;
    });
    distinctArr.forEach(function(el) {
        delete el.inArray;
    });
    return distinctArr;
}
2019编辑:现代版本的JavaScript使这个问题更容易解决。无论数组是否包含对象、字符串、数字或任何其他类型,使用
Set
都会起作用

function getDistinctArray(arr) {
    return [...new Set(arr)];
}
实现非常简单,不再需要定义函数。

使用
function getDistinctArray(arr) {
    var dups = {};
    return arr.filter(function(el) {
        var hash = el.valueOf();
        var isDup = dups[hash];
        dups[hash] = true;
        return !isDup;
    });
}
function getDistinctObjArray(arr) {
    var distinctArr = arr.filter(function(el) {
        var isDup = el.inArray;
        el.inArray = true;
        return !isDup;
    });
    distinctArr.forEach(function(el) {
        delete el.inArray;
    });
    return distinctArr;
}
function getDistinctArray(arr) {
    return [...new Set(arr)];
}
arr = arr.filter (function (value, index, array) { 
    return array.indexOf (value) == index;
});
var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];

var uniq = names.reduce(function(a,b){
    if (a.indexOf(b) < 0 ) a.push(b);
    return a;
  },[]);

console.log(uniq, names) // [ 'Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Carl' ]

// one liner
return names.reduce(function(a,b){if(a.indexOf(b)<0)a.push(b);return a;},[]);
var uniq = names.slice() // slice makes copy of array before sorting it
  .sort(function(a,b){
    return a > b;
  })
  .reduce(function(a,b){
    if (a.slice(-1)[0] !== b) a.push(b); // slice(-1)[0] means last item in array without removing it (like .pop())
    return a;
  },[]); // this empty array becomes the starting value for a

// one liner
return names.slice().sort(function(a,b){return a > b}).reduce(function(a,b){if (a.slice(-1)[0] !== b) a.push(b);return a;},[]);
var uniq = [ ...new Set(names) ]; // [ 'Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Carl' ]
var names = ['Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl']

var uniq = names
  .map((name) => {
    return {count: 1, name: name}
  })
  .reduce((a, b) => {
    a[b.name] = (a[b.name] || 0) + b.count
    return a
  }, {})

var sorted = Object.keys(uniq).sort((a, b) => uniq[a] < uniq[b])

console.log(sorted)
function contains(array, obj) {
    for (var i = 0; i < array.length; i++) {
        if (isEqual(array[i], obj)) return true;
    }
    return false;
}
//comparator
function isEqual(obj1, obj2) {
    if (obj1.name == obj2.name) return true;
    return false;
}
function removeDuplicates(ary) {
    var arr = [];
    return ary.filter(function(x) {
        return !contains(arr, x) && arr.push(x);
    });
}
$(document).ready(function() {

    var arr1=["dog","dog","fish","cat","cat","fish","apple","orange"]

    var arr2=["cat","fish","mango","apple"]

    var uniquevalue=[];
    var seconduniquevalue=[];
    var finalarray=[];

    $.each(arr1,function(key,value){

       if($.inArray (value,uniquevalue) === -1)
       {
           uniquevalue.push(value)

       }

    });

     $.each(arr2,function(key,value){

       if($.inArray (value,seconduniquevalue) === -1)
       {
           seconduniquevalue.push(value)

       }

    });

    $.each(uniquevalue,function(ikey,ivalue){

        $.each(seconduniquevalue,function(ukey,uvalue){

            if( ivalue == uvalue)

            {
                finalarray.push(ivalue);
            }   

        });

    });
    alert(finalarray);
});
var names = ["Alex","Tony","James","Suzane", "Marie", "Laurence", "Alex", "Suzane", "Marie", "Marie", "James", "Tony", "Alex"];
var uniqueNames = [];

    for(var i in names){
        if(uniqueNames.indexOf(names[i]) === -1){
            uniqueNames.push(names[i]);
        }
    }
var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"],
    unique = [...new Set(names)];
var uniqueArray = duplicateArray.filter(function(elem, pos) {
    return duplicateArray.indexOf(elem) == pos;
}); 
Feature Chrome  Firefox (Gecko)     Internet Explorer   Opera   Safari
Basic support   (Yes)   1.5 (1.8)   9                   (Yes)   (Yes)
var duplicates = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl","Mike","Mike","Nancy","Carl"]; 
var unique = duplicates.filter(function(elem, pos) {
    return duplicates.indexOf(elem) == pos;
  }); 
alert(unique);
d3.set(["foo", "bar", "foo", "baz"]).values() ==> ["foo", "bar", "baz"]
vals.sort().reduce(function(a, b){ if (b != a[0]) a.unshift(b); return a }, [])
vals.filter(function(v, i, a){ return i == a.indexOf(v) })
Array.from(new Set(vals))
[...new Set(vals)]
var uniqueArray = dupeArray.filter(function(item, i, self){
  return self.lastIndexOf(item) == i;
});
var peoplenames = new Array("Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl");

peoplenames = unique(peoplenames);
alert(peoplenames);

function unique(array){
    var len = array.length;
    for(var i = 0; i < len; i++) for(var j = i + 1; j < len; j++) 
        if(array[j] == array[i]){
            array.splice(j,1);
            j--;
            len--;
        }
    return array;
}

//*result* peoplenames == ["Mike","Matt","Nancy","Adam","Jenny","Carl"]
 var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl", "Mike", "Nancy"]

 var noDupe = Array.from(new Set(names))
let a = [11,22,11,22];
let b = []


b = [ ...new Set(a) ];     
// b = [11, 22]

b = Array.from( new Set(a))   
// b = [11, 22]

b = a.filter((val,i)=>{
  return a.indexOf(val)==i
})                        
// b = [11, 22]
Array.prototype.unique = function() {
    var a = [];
    for (i = 0; i < this.length; i++) {
        var current = this[i];
        if (a.indexOf(current) < 0) a.push(current);
    }
    return a;
}
Array.prototype.unique = function() {
    return Array.from(new Set(this));
}
var x=[1,2,3,3,2,1];
x.unique() //[1,2,3]
var a = [2,3,4,5,5,4];
a.filter(function(value, index){ return a.indexOf(value) == index });
a.filter((v,i) => a.indexOf(v) == i)
function removeDuplicates(arr){
    o={}
    arr.forEach(function(e){
        o[e]=true
    })
    return Object.keys(o)
}
let names = ['Mike','Matt','Nancy','Adam','Jenny','Nancy','Carl', 'Nancy'];
let dup = [...new Set(names)];
console.log(dup);
for (i=0; i<originalArray.length; i++) {  
    if (!newArray.includes(originalArray[i])) {
        newArray.push(originalArray[i]); 
    }
}