我有这段代码:
var ar = [10,7,8,3,4,7,6];
function isin(n,a){
for (var i=0;i<a.length;i++){
if (a[i]== n) {
var b = true;
return b;
} else {
var c = false;
return c;
}
}
}
function unique(a){
var arr = [];
for (var i=0;i<a.length;i++){
if (!isin(a[i],arr)){
arr.push(a[i]);
}
}
return arr;
}
alert(unique(ar));
在这段代码中,我尝试从原始数组中创建新的唯一数组(没有重复数组)。 但我仍然得到原始阵列!哪里是我的错?
答案 0 :(得分:65)
或者那些寻找单线程(简单且功能齐全)的人:
var a = ["1", "1", "2", "3", "3", "1"];
var unique = a.filter(function(item, i, ar){ return ar.indexOf(item) === i; });
答案 1 :(得分:47)
使用普通数组并返回关联数组的键(仅包含给定数组中的“唯一”值)更有效:
function ArrNoDupe(a) {
var temp = {};
for (var i = 0; i < a.length; i++)
temp[a[i]] = true;
var r = [];
for (var k in temp)
r.push(k);
return r;
}
$(document).ready(function() {
var arr = [10, 7, 8, 3, 4, 3, 7, 6];
var noDupes = ArrNoDupe(arr);
$("#before").html("Before: " + arr.join(", "));
$("#after").html("After: " + noDupes.join(", "));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="before"></div>
<div id="after"></div>
注意:该功能不保留项目的顺序,因此如果这很重要,请使用不同的逻辑。
从IE9和所有其他现代浏览器(例如Chrome,Firefox)开始,使用Object.keys()
方法可以提高效率:
function ArrNoDupe(a) {
var temp = {};
for (var i = 0; i < a.length; i++)
temp[a[i]] = true;
return Object.keys(temp);
}
$(document).ready(function() {
var arr = [10, 7, 8, 3, 4, 3, 7, 6];
var noDupes = ArrNoDupe(arr);
$("#before").html("Before: " + arr.join(", "));
$("#after").html("After: " + noDupes.join(", "));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="before"></div>
<div id="after"></div>
感谢wateriswet bringing this to my attention。 :)子>
答案 2 :(得分:15)
您可以使用新的原生new Set(list)
object in ES6/ES2015。 (即Babel,Typescript,或者幸运的是所有目标浏览器都支持ES2015)。
// I never use this, because it's an iterator, not an array
let s = new Set(list);
或者,如果您想链接到数组助手,请使用ES6 / ES2015中新的...
扩展运算符将其扩展到数组中:
const unique = (list) => {
return [...new Set(list)];
}
您需要一个数组来链接sort()
:
const convertText = (textToConvert) => {
let list = unique(textToConvert.split(/\r?\n/g))
.sort() // this will error if using uniqueAsIterator() version...
.filter(x => x != "NULL");
return list;
}
答案 3 :(得分:9)
除了使用Josh Mc的过滤器响应之外,你还可以使用箭头功能实用程序在es6中缩短它的速度;
const a = ["1", "1", "2", "3", "3", "1"];
let unique = a.filter((it, i, ar) => ar.indexOf(it) === i);
// unique = [1, 2, 3]
答案 4 :(得分:8)
修改:注意warning by Daniel。考虑到这一点,以及官方文档的说法(下文),也许使用它毕竟不是一个好主意!
如果你碰巧使用jQuery,它的unique()
function会这样做:
var ar = [1, 2, 1, 2, 2, 3];
ar = $.unique(ar);
console.log(ar); // [3, 2, 1]
文档说:
请注意,这仅适用于DOM元素的数组,而不适用于字符串或 号。
...但是当我使用jQuery 1.9.1进行测试时,它 也适用于字符串和数字。无论如何,仔细检查它是否有效,特别是如果使用旧的jQuery。
答案 5 :(得分:3)
因为在检查第一个元素后,isin
方法返回true或false。
将其更改为:
function isin(n,a){
for (var i=0;i<a.length;i++){
if (a[i]== n){
return true;
}
}
return false;
}
答案 6 :(得分:3)
有一些ES5的乐趣......
function uniqueArray(array) {
var temp = array.reduce(function(previous, current) {
previous[current] = true;
return previous;
}, {});
return Object.keys(temp);
}
答案 7 :(得分:2)
您应该使用indexOf而不是isIn函数:
function unique(a){
var arr = [];
for (var i=0;i<a.length;i++){
if ( arr.indexOf(a[i]) == -1){
arr.push(a[i]);
}
}
答案 8 :(得分:1)
哪里是我的错误?
就在这里:
... else {
var c = false;
return c;
}
如果isin
与数组中的第一个元素不匹配,则会导致n
函数为false。在进入下一个元素之前,循环体将始终返回一个值。
删除else子句并将return false
移到方法的底部:
function isin(n,a){
for (var i=0;i<a.length;i++) {
if (a[i] == n)
return true;
return false;
}
请注意,isin
方法可以立即(或甚至替换为)indexOf
调用实施。
答案 9 :(得分:1)
我这样做的方法是使用“向后”的数组,所以当我按下它时,我使用键而不是值,如下所示:
var arr = [];
$('input[type=checkbox]', SearchResults).each( function() {
if( $(this).is(':checked') )
arr[ $(this).data('client_id') ] = true;
}
然后我看着键而不是值。
答案 10 :(得分:1)
我知道我有点迟到回答这个问题。但没有一个答案符合我的要求。我喜欢使用拼接来做这种事情。这是一个非常简单的脚本,可以完全满足您的需求:
function unique(originalArray){
var ar = originalArray.slice(0);//Make a copy of the array and store it in ar
var i = ar.length;
while(i--){ //Iterate through the array
if(ar.indexOf(ar[i],i+1)>-1){ //If the array has a duplicate
ar.splice(i,1); //Remove that element!
}
}
return ar; //Return the new, more unique array
}
答案 11 :(得分:0)
基于accepted answer。这是CoffeeScript的等价物:
unique = (a) ->
temp = {}
for i in [0...a.length]
temp[a[i]] = true
r = []
for k of temp
r.push(k)
return r
答案 12 :(得分:0)
答案 13 :(得分:0)
我知道的最简单版本:Array.from(new Set(duplicateArray))
答案 14 :(得分:0)
扩展上面的Jamiecs'答案,这里是Array.prototype.
的答案。
var arr = [1, 1, 1, 2, 5, 6, 4, 5 , 1];
Array.prototype.uniqueArr = function() {
var arr = [];
for (var i=0;i<this.length;i++) {
if ( arr.indexOf(this[i]) == -1 ) {
arr.push(this[i]);
}
}
return arr
}
var arr = arr.uniqueArr();
console.log(arr);
答案 15 :(得分:0)
使用过滤器功能
const getUnique = (arr) => {
return arr.filter((val, i, _self) => {
return _self.indexOf(val) === i;
});
}
let arr = [1,2,1,3,4,2];
console.log(getUnique(arr)); // [ 1, 2, 3, 4 ]