J'ai un tableau JavaScript comme ceci:
var myData=['237','124','255','124','366','255'];
J'ai besoin que les éléments du tableau soient uniques et triés:
myData[0]='124';
myData[1]='237';
myData[2]='255';
myData[3]='366';
Même si les membres de array ressemblent à des entiers , ce sont pas des entiers , puisque j'ai déjà converti chacun en chaîne:
var myData[0]=num.toString();
//...and so on.
Est-il possible de faire toutes ces tâches en JavaScript?
C'est en fait très simple. Il est beaucoup plus facile de trouver des valeurs uniques si les valeurs sont triées en premier:
function sort_unique(arr) {
if (arr.length === 0) return arr;
arr = arr.sort(function (a, b) { return a*1 - b*1; });
var ret = [arr[0]];
for (var i = 1; i < arr.length; i++) { //Start loop at 1: arr[0] can never be a duplicate
if (arr[i-1] !== arr[i]) {
ret.Push(arr[i]);
}
}
return ret;
}
console.log(sort_unique(['237','124','255','124','366','255']));
//["124", "237", "255", "366"]
Cela peut convenir dans des circonstances où vous ne pouvez pas définir la fonction à l’avance (comme dans un bookmarklet):
myData.sort().filter(function(el,i,a){return i===a.indexOf(el)})
function sort_unique(arr) {
return arr.sort().filter(function(el,i,a) {
return (i==a.indexOf(el));
});
}
Voici mon approche (plus moderne) utilisant Array.protoype.reduce()
:
[2, 1, 2, 3].reduce((a, x) => a.includes(x) ? a : [...a, x], []).sort()
// returns [1, 2, 3]
Edit: Version plus performante comme indiqué dans les commentaires:
arr.sort().filter((x, i, a) => !i || x != a[i-1])
Vous pouvez maintenant obtenir le résultat en seulement un ligne de code.
Utilisation de new Set pour réduire le tableau à un ensemble unique de valeurs . Appliquez la méthode sort après pour ordonner les valeurs de chaîne.
var myData=['237','124','255','124','366','255']
var uniqueAndSorted = [...new Set(myData)].sort()
UPDATED _ pour les méthodes plus récentes introduites dans JavaScript depuis le moment de la question.
Que diriez-vous:
array.sort().filter(function(elem, index, arr) {
return index == arr.length - 1 || arr[index + 1] != elem
})
Ceci est similaire à @loostro answer, mais au lieu d'utiliser indexOf qui réitère le tableau pour chaque élément afin de vérifier qu'il est le premier trouvé, il vérifie simplement que l'élément suivant est différent de l'élément actuel.
Essayez d’utiliser une bibliothèque externe comme underscore
var f = _.compose(_.uniq, function(array) {
return _.sortBy(array, _.identity);
});
var sortedUnique = f(array);
Cela repose sur _.compose
, _.uniq
, _.sortBy
, _.identity
Voir en direct exemple
Qu'est-ce que ça fait?
Nous voulons une fonction qui prend un tableau puis retourne un tableau trié avec les entrées non uniques supprimées. Cette fonction doit faire deux choses, trier et rendre le tableau unique.
C'est un bon travail pour la composition, nous composons donc la fonction unique & sort ensemble. _.uniq
peut simplement être appliqué sur le tableau avec un argument, il est donc simplement passé à _.compose
la fonction _.sortBy a besoin d'une fonction de tri conditionnel. il attend une fonction qui retourne une valeur et le tableau sera trié sur cette valeur. Puisque la valeur que nous ordonnons est la valeur du tableau, nous pouvons simplement passer la fonction _.identity.
Nous avons maintenant une composition de fonction qui (prend un tableau et retourne un tableau unique) et une fonction qui (prend un tableau et retourne un tableau trié, trié par valeur).
Nous appliquons simplement la composition sur le tableau et nous avons notre tableau trié de manière unique.
Cette fonction n'échoue pas pour plus de deux valeurs en double:
function unique(arr) {
var a = [];
var l = arr.length;
for(var i=0; i<l; i++) {
for(var j=i+1; j<l; j++) {
// If a[i] is found later in the array
if (arr[i] === arr[j])
j = ++i;
}
a.Push(arr[i]);
}
return a;
};
Pas de tableau "retour" redondant, pas d'ECMA5 intégré (j'en suis sûr!) Et simple à lire.
function removeDuplicates(target_array) {
target_array.sort();
var i = 0;
while(i < target_array.length) {
if(target_array[i] === target_array[i+1]) {
target_array.splice(i+1,1);
}
else {
i += 1;
}
}
return target_array;
}
Une façon d'utiliser une fonction de tri personnalisée
//func has to return 0 in the case in which they are equal
sort_unique = function(arr,func) {
func = func || function (a, b) {
return a*1 - b*1;
};
arr = arr.sort(func);
var ret = [arr[0]];
for (var i = 1; i < arr.length; i++) {
if (func(arr[i-1],arr[i]) != 0)
ret.Push(arr[i]);
}
}
return ret;
}
Exemple: ordre de desc pour un tableau d'objets
MyArray = sort_unique(MyArray , function(a,b){
return b.iterator_internal*1 - a.iterator_internal*1;
});
Je suppose que je posterai cette réponse pour une variété. Cette technique de suppression des doublons a été choisie pour un projet Flash sur lequel je travaille actuellement il y a environ un mois.
Ce que vous faites est de créer un objet et de le remplir avec une clé et une valeur en utilisant chaque élément du tableau. Étant donné que les clés en double sont supprimées, les doublons sont supprimés.
var nums = [1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10];
var newNums = purgeArray(nums);
function purgeArray(ar)
{
var obj = {};
var temp = [];
for(var i=0;i<ar.length;i++)
{
obj[ar[i]] = ar[i];
}
for (var item in obj)
{
temp.Push(obj[item]);
}
return temp;
}
Il y a déjà 5 autres réponses, donc je ne vois pas la nécessité de poster une fonction de tri.
Les solutions O [N ^ 2] sont mauvaises, en particulier lorsque les données sont déjà triées, il n'est pas nécessaire de créer deux boucles imbriquées pour supprimer les doublons. Une boucle et comparer à l'élément précédent fonctionnera très bien.
Une solution simple avec O [] de sort () suffirait. Ma solution est:
function sortUnique(arr, compareFunction) {
let sorted = arr.sort(compareFunction);
let result = sorted.filter(compareFunction
? function(val, i, a) { return (i == 0 || compareFunction(a[i-1], val) != 0); }
: function(val, i, a) { return (i == 0 || a[i-1] !== val); }
);
return result;
}
BTW, peut faire quelque chose comme ceci pour avoir la méthode Array.sortUnique ():
Array.prototype.sortUnique = function(compareFunction) {return sortUnique(this, compareFunction); }
En outre, sort () pourrait être modifié pour supprimer le deuxième élément si la fonction compare () renvoie 0 (éléments égaux), bien que ce code puisse devenir compliqué (nécessité de réviser les limites de la boucle dans le vol). De plus, je me garde de faire mes propres fonctions sort () dans les langages interprétés, car cela dégraderait très certainement les performances. Donc, cet ajout est pour la considération ECMA 2019+.
Voici un simple liner avec O(N)
, en supposant que:
Ensuite
> Object.keys([{}].concat(['a', 'b', 'a']).reduce((l,r) => l[r] = l ))
[ 'a', 'b' ]
Explication
Jeu de données d'origine, supposons qu'il vienne d'une fonction externe
let data = ['a', 'b', 'a']
Nous voulons ajouter un objet devant le tableau
let setup = [{}].concat(data)
Ensuite, nous voulons réduire le tableau en une seule valeur.
Dans l'étape précédente, nous avons ajouté l'objet au tableau afin que nous puissions coller toutes les valeurs sur cet objet, en tant que clés, dans cette étape. Le résultat final est un objet avec un ensemble unique de clés.
let reduced = setup.reduce((l,r) => l[r] = l)
Nous définissons l[r] = l
car en javascript, la valeur de l'expression d'affectation est renvoyée lorsqu'une instruction d'affectation est utilisée comme expression.
Ensuite, nous voulons obtenir les clés de cet objet
let keys = Object.keys(setup)
Quel est l'ensemble des valeurs uniques du tableau d'origine
['a', 'b']
function sort () seulement n'est valable que si votre numéro a le même chiffre, exemple:
var myData = ["3","11","1","2"]
reviendrai
var myData = ["1","11","2","3"]
et ici l'amélioration de la fonction de mrmonkington
myData.sort().sort(function(a,b){return a - b;}).filter(function(el,i,a){if(i==a.indexOf(el) & el.length>0)return 1;return 0;})
la fonction ci-dessus supprimera également le tableau vide et vous pourrez vérifier la démo ci-dessous
http://jsbin.com/ahojip/2/edit
// Another way, that does not rearrange the original Array
// and spends a little less time handling duplicates.
function uniqueSort(arr, sortby){
var A1= arr.slice();
A1= typeof sortby== 'function'? A1.sort(sortby): A1.sort();
var last= A1.shift(), next, A2= [last];
while(A1.length){
next= A1.shift();
while(next=== last) next= A1.shift();
if(next!=undefined){
A2[A2.length]= next;
last= next;
}
}
return A2;
}
var myData= ['237','124','255','124','366','255','100','1000'];
uniqueSort(myData,function(a,b){return a-b})
// the ordinary sort() returns the same array as the number sort here,
// but some strings of digits do not sort so nicely numerical.