I have this code:
我有这个代码:
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));
In this code, I try to create new unique array (without duplicates) out of the original one. But I still get the original array! Where's my mistake?
在这段代码中,我尝试从原始数组创建新的唯一数组(没有重复)。但我仍然得到原始阵列!哪里是我的错?
13 个解决方案
#1
42
Using a plain array and returning the keys of associative array (containing only the "unique" values from given array) is more efficient:
使用普通数组并返回关联数组的键(仅包含给定数组中的“唯一”值)更有效:
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>
Note: The function does not preserve the order of the items, so if this is important use different logic.
注意:该函数不保留项的顺序,因此如果这很重要,请使用不同的逻辑。
As of IE9 and on all other modern browsers (e.g. Chrome, Firefox) this can become even more efficient by using the Object.keys()
method:
从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>
Thanks wateriswet for bringing this to my attention. :)
感谢wateriswet引起我的注意。 :)
#2
41
Or for those looking for a one-liner (simple and functional):
或者对于那些寻找单线程(简单且功能齐全)的人:
var a = ["1", "1", "2", "3", "3", "1"];
var unique = a.filter(function(item, i, ar){ return ar.indexOf(item) === i; });
#3
9
You could use the new native new Set(list)
object in ES6/ES2015. (i.e. Babel, Typescript, or those lucky enough that all target browsers support ES2015).
您可以在ES6 / ES2015中使用新的本机新Set(list)对象。 (即Babel,Typescript,或者幸运的是所有目标浏览器都支持ES2015)。
// I never use this, because it's an iterator, not an array
let s = new Set(list);
or, if you want to chain to array helpers use the new ...
spread operator in ES6/ES2015 to spread it into an array:
或者,如果要链接到数组助手,请使用ES6 / ES2015中的新... spread运算符将其扩展到数组中:
const unique = (list) => {
return [...new Set(list)];
}
You need an array to chain methods like sort()
:
你需要一个数组链接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;
}
#4
8
Edit: note the warning by Daniel. Considering that, and what the official docs say (below), maybe using this is not a great idea after all!
编辑:注意丹尼尔的警告。考虑到这一点,以及官方文档的说法(下文),也许使用它毕竟不是一个好主意!
If you happen to use jQuery, its unique()
function does this:
如果你碰巧使用jQuery,它的unique()函数会这样做:
var ar = [1, 2, 1, 2, 2, 3];
ar = $.unique(ar);
console.log(ar); // [3, 2, 1]
The documentation says:
文件说:
Note that this only works on arrays of DOM elements, not strings or numbers.
请注意,这仅适用于DOM元素的数组,而不适用于字符串或数字。
...but when I tested this with jQuery 1.9.1, it does work for strings and numbers too. Anyway, double-check that it works, especially if using older jQuery.
...但是当我用jQuery 1.9.1测试它时,它确实适用于字符串和数字。无论如何,仔细检查它是否有效,特别是如果使用旧的jQuery。
#5
6
In addition to usage of filter respond by Josh Mc, you can make it crazy shorter in es6 with arrow function utility;
除了使用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]
#6
3
Because your isin
method returns true or false after examining the first element.
因为你的isin方法在检查第一个元素后返回true或false。
change it to this:
把它改成这个:
function isin(n,a){
for (var i=0;i<a.length;i++){
if (a[i]== n){
return true;
}
}
return false;
}
#7
2
You should use indexOf instead of your isIn function:
您应该使用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
2
And with some ES5 fun...
有一些ES5的乐趣......
function uniqueArray(array) {
var temp = array.reduce(function(previous, current) {
previous[current] = true;
return previous;
}, {});
return Object.keys(temp);
}
#9
1
Where's my mistake??
哪里是我的错?
Right here:
就在这儿:
... else {
var c = false;
return c;
}
This causes the isin
function to false if n
doesn't match the first element in the array. The loop-body will always return a value before progressing to the next element.
如果n与数组中的第一个元素不匹配,则会导致isin函数为false。在进入下一个元素之前,循环体将始终返回一个值。
Remove the else-clause and move return false
to the bottom of the method:
删除else子句并将return false移到方法的底部:
function isin(n,a){
for (var i=0;i<a.length;i++) {
if (a[i] == n)
return true;
return false;
}
Note that the isin
method can be implemented immediately (or even replaced by) a call to indexOf
.
请注意,isin方法可以立即执行(甚至替换为)对indexOf的调用。
#10
1
The way I did it was to use the array "backwards", so when I push to it I use the key instead of the value, like this:
我这样做的方法是使用“向后”的数组,所以当我按下它时,我使用键而不是值,如下所示:
var arr = [];
$('input[type=checkbox]', SearchResults).each( function() {
if( $(this).is(':checked') )
arr[ $(this).data('client_id') ] = true;
}
Then I look at the keys rather than the values.
然后我看看键而不是值。
#11
1
I know I'm somewhat late to answer this. But none of the answers have what I would do. I like using splice for this sort of thing. Here's a really simple script that'll do exactly what you need:
我知道我回答这个问题有点迟了。但是没有一个答案符合我的要求。我喜欢使用拼接来做这种事情。这是一个非常简单的脚本,它可以完全满足您的需求:
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
}
#12
0
Based on the accepted answer. Here is a CoffeeScript equivalent:
根据接受的答案。这是CoffeeScript的等价物:
unique = (a) ->
temp = {}
for i in [0...a.length]
temp[a[i]] = true
r = []
for k of temp
r.push(k)
return r
#13
0
I've done a similar search, I found this answer really good:
我做了类似的搜索,我发现这个答案非常好:
Unique values in an array [duplicate]
数组中的唯一值[重复]
You can re-use those function on other code. This is also good approach where it is compatible with many browsers.
您可以在其他代码上重用这些功能。这也是与许多浏览器兼容的好方法。
Cheer.
欢呼。
#1
42
Using a plain array and returning the keys of associative array (containing only the "unique" values from given array) is more efficient:
使用普通数组并返回关联数组的键(仅包含给定数组中的“唯一”值)更有效:
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>
Note: The function does not preserve the order of the items, so if this is important use different logic.
注意:该函数不保留项的顺序,因此如果这很重要,请使用不同的逻辑。
As of IE9 and on all other modern browsers (e.g. Chrome, Firefox) this can become even more efficient by using the Object.keys()
method:
从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>
Thanks wateriswet for bringing this to my attention. :)
感谢wateriswet引起我的注意。 :)
#2
41
Or for those looking for a one-liner (simple and functional):
或者对于那些寻找单线程(简单且功能齐全)的人:
var a = ["1", "1", "2", "3", "3", "1"];
var unique = a.filter(function(item, i, ar){ return ar.indexOf(item) === i; });
#3
9
You could use the new native new Set(list)
object in ES6/ES2015. (i.e. Babel, Typescript, or those lucky enough that all target browsers support ES2015).
您可以在ES6 / ES2015中使用新的本机新Set(list)对象。 (即Babel,Typescript,或者幸运的是所有目标浏览器都支持ES2015)。
// I never use this, because it's an iterator, not an array
let s = new Set(list);
or, if you want to chain to array helpers use the new ...
spread operator in ES6/ES2015 to spread it into an array:
或者,如果要链接到数组助手,请使用ES6 / ES2015中的新... spread运算符将其扩展到数组中:
const unique = (list) => {
return [...new Set(list)];
}
You need an array to chain methods like sort()
:
你需要一个数组链接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;
}
#4
8
Edit: note the warning by Daniel. Considering that, and what the official docs say (below), maybe using this is not a great idea after all!
编辑:注意丹尼尔的警告。考虑到这一点,以及官方文档的说法(下文),也许使用它毕竟不是一个好主意!
If you happen to use jQuery, its unique()
function does this:
如果你碰巧使用jQuery,它的unique()函数会这样做:
var ar = [1, 2, 1, 2, 2, 3];
ar = $.unique(ar);
console.log(ar); // [3, 2, 1]
The documentation says:
文件说:
Note that this only works on arrays of DOM elements, not strings or numbers.
请注意,这仅适用于DOM元素的数组,而不适用于字符串或数字。
...but when I tested this with jQuery 1.9.1, it does work for strings and numbers too. Anyway, double-check that it works, especially if using older jQuery.
...但是当我用jQuery 1.9.1测试它时,它确实适用于字符串和数字。无论如何,仔细检查它是否有效,特别是如果使用旧的jQuery。
#5
6
In addition to usage of filter respond by Josh Mc, you can make it crazy shorter in es6 with arrow function utility;
除了使用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]
#6
3
Because your isin
method returns true or false after examining the first element.
因为你的isin方法在检查第一个元素后返回true或false。
change it to this:
把它改成这个:
function isin(n,a){
for (var i=0;i<a.length;i++){
if (a[i]== n){
return true;
}
}
return false;
}
#7
2
You should use indexOf instead of your isIn function:
您应该使用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
2
And with some ES5 fun...
有一些ES5的乐趣......
function uniqueArray(array) {
var temp = array.reduce(function(previous, current) {
previous[current] = true;
return previous;
}, {});
return Object.keys(temp);
}
#9
1
Where's my mistake??
哪里是我的错?
Right here:
就在这儿:
... else {
var c = false;
return c;
}
This causes the isin
function to false if n
doesn't match the first element in the array. The loop-body will always return a value before progressing to the next element.
如果n与数组中的第一个元素不匹配,则会导致isin函数为false。在进入下一个元素之前,循环体将始终返回一个值。
Remove the else-clause and move return false
to the bottom of the method:
删除else子句并将return false移到方法的底部:
function isin(n,a){
for (var i=0;i<a.length;i++) {
if (a[i] == n)
return true;
return false;
}
Note that the isin
method can be implemented immediately (or even replaced by) a call to indexOf
.
请注意,isin方法可以立即执行(甚至替换为)对indexOf的调用。
#10
1
The way I did it was to use the array "backwards", so when I push to it I use the key instead of the value, like this:
我这样做的方法是使用“向后”的数组,所以当我按下它时,我使用键而不是值,如下所示:
var arr = [];
$('input[type=checkbox]', SearchResults).each( function() {
if( $(this).is(':checked') )
arr[ $(this).data('client_id') ] = true;
}
Then I look at the keys rather than the values.
然后我看看键而不是值。
#11
1
I know I'm somewhat late to answer this. But none of the answers have what I would do. I like using splice for this sort of thing. Here's a really simple script that'll do exactly what you need:
我知道我回答这个问题有点迟了。但是没有一个答案符合我的要求。我喜欢使用拼接来做这种事情。这是一个非常简单的脚本,它可以完全满足您的需求:
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
}
#12
0
Based on the accepted answer. Here is a CoffeeScript equivalent:
根据接受的答案。这是CoffeeScript的等价物:
unique = (a) ->
temp = {}
for i in [0...a.length]
temp[a[i]] = true
r = []
for k of temp
r.push(k)
return r
#13
0
I've done a similar search, I found this answer really good:
我做了类似的搜索,我发现这个答案非常好:
Unique values in an array [duplicate]
数组中的唯一值[重复]
You can re-use those function on other code. This is also good approach where it is compatible with many browsers.
您可以在其他代码上重用这些功能。这也是与许多浏览器兼容的好方法。
Cheer.
欢呼。