J'ai ce 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));
Dans ce code, j'essaie de créer un nouveau tableau unique (sans doublons) à partir de celui d'origine . Mais j'obtiens toujours le tableau d'origine! Où est mon erreur?
L'utilisation d'un tableau simple et le renvoi des clés d'un tableau associatif (contenant uniquement les valeurs "uniques" d'un tableau donné) sont plus efficaces:
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>
Remarque: La fonction ne conserve pas l'ordre des éléments. Si c'est important, utilisez une logique différente.
À partir d'IE9 et de tous les autres navigateurs modernes (par exemple, Chrome, Firefox), cela peut devenir encore plus efficace en utilisant la méthode 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>
Merci wateriswet pour ce qui a attiré mon attention . :)
Ou pour ceux qui recherchent un one-liner (simple et fonctionnel):
var a = ["1", "1", "2", "3", "3", "1"];
var unique = a.filter(function(item, i, ar){ return ar.indexOf(item) === i; });
Vous pouvez utiliser le nouvel objet natif new Set(list)
dans ES6/ES2015 . (c’est-à-dire Babel, TypeScript ou ceux qui ont la chance que tous les navigateurs cibles prennent en charge ES2015).
// I never use this, because it's an iterator, not an array
let s = new Set(list);
ou, si vous souhaitez enchaîner des assistants de tableau, utilisez le nouvel opérateur de propagation ...
dans ES6/ES2015 pour le diffuser dans un tableau:
const unique = (list) => {
return [...new Set(list)];
}
Vous avez besoin d'un tableau pour chaîner des méthodes telles que 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;
}
Edit: notez l'avertissement de Daniel . Compte tenu de cela et de ce que disent les médecins officiels (ci-dessous), utiliser ce n’est peut-être pas une bonne idée après tout!
Si vous utilisez jQuery, sa fonction unique()
fait ceci:
var ar = [1, 2, 1, 2, 2, 3];
ar = $.unique(ar);
console.log(ar); // [3, 2, 1]
La documentation dit:
Notez que cela ne fonctionne que sur les tableaux d’éléments DOM, pas de chaînes ni Nombres.
... mais quand j’ai testé cela avec jQuery 1.9.1, fonctionne aussi pour les chaînes et les nombres. Quoi qu'il en soit, vérifiez que cela fonctionne, surtout si vous utilisez jQuery plus ancien.
En plus de l’utilisation de filtre répond par Josh Mc, vous pouvez le rendre plus court dans es6 avec la fonction de flèche
const a = ["1", "1", "2", "3", "3", "1"];
let unique = a.filter((it, i, ar) => ar.indexOf(it) === i);
// unique = [1, 2, 3]
Parce que votre méthode isin
renvoie true ou false après avoir examiné le premier élément.
changez cela en ceci:
function isin(n,a){
for (var i=0;i<a.length;i++){
if (a[i]== n){
return true;
}
}
return false;
}
Et avec un peu de plaisir ES5 ...
function uniqueArray(array) {
var temp = array.reduce(function(previous, current) {
previous[current] = true;
return previous;
}, {});
return Object.keys(temp);
}
Vous devriez utiliser indexOf au lieu de votre fonction isIn:
function unique(a){
var arr = [];
for (var i=0;i<a.length;i++){
if ( arr.indexOf(a[i]) == -1){
arr.Push(a[i]);
}
}
Je sais que je suis un peu en retard pour répondre à cela. Mais aucune des réponses n'a ce que je ferais. J'aime utiliser l'épissure pour ce genre de chose. Voici un script très simple qui fera exactement ce dont vous avez besoin:
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
}
La façon dont je l'ai fait était d'utiliser le tableau "à l'envers", donc quand j'appuie dessus, j'utilise la clé au lieu de la valeur, comme ceci:
var arr = [];
$('input[type=checkbox]', SearchResults).each( function() {
if( $(this).is(':checked') )
arr[ $(this).data('client_id') ] = true;
}
Ensuite, je regarde les clés plutôt que les valeurs.
Où est mon erreur ??
Ici:
... else {
var c = false;
return c;
}
La fonction isin
est définie sur false si n
ne correspond pas à le premier élément du tableau. Le corps de la boucle retournera toujours une valeur avant de passer à l'élément suivant.
Supprimez la clause else et déplacez return false
au bas de la méthode:
function isin(n,a){
for (var i=0;i<a.length;i++) {
if (a[i] == n)
return true;
return false;
}
Notez que la méthode isin
peut être implémentée immédiatement (ou même remplacée par) un appel à indexOf
.
J'ai fait une recherche similaire, j'ai trouvé cette réponse vraiment bonne:
Valeurs uniques dans un tableau [duplicate]
Vous pouvez réutiliser ces fonctions sur un autre code . C'est également une bonne approche si elle est compatible avec de nombreux navigateurs.
Acclamation.
Basé sur la réponse acceptée . Voici un équivalent de CoffeeScript:
unique = (a) ->
temp = {}
for i in [0...a.length]
temp[a[i]] = true
r = []
for k of temp
r.Push(k)
return r