Je voudrais savoir s'il existe en JavaScript une fonction standard qui,
à partir d'un tableau de chaînes dont certaines sont présentes plusieurs
fois, n'en garde qu'une ? L'idéal serait que la fonction soit couplée
avec le tri du tableau.
Par exemple, si en entrée j'ai ceci :
{ "fleur", "arbre", "gazon", "fleur", "plante", "fleur", "arbre" }
en sortie j'aurais cela :
{ "arbre", "fleur", "gazon", "plante" }
Je n'ai rien trouvé dans la partie /Array/ de fr.selfhtml.org. Si la
fonction n'existe pas en natif, merci de ne pas passer de temps à me
coder une fonction équivalente : j'utiliserai un autre moyen qui sera
plus rapide qu'un tri avec élimination des doublons.
Cordialement,
--
Olivier Miakinen
Non, monsieur le juge, je vous le jure : jamais je n'ai cité
Bruxelles dans ma signature.
Le seul problème avec cet algo (performant) est que l'Array de départ est modifiée, du coup le "return" se justifie moins et peut même, à la limite, tromper son monde ! Pour ma part, j'enlèverais cette dernière ligne...
Je m'étais dit la même chose que toi, mais sans cette ligne si on écrit alert(a.uniq()); on a droit a un beau undefined, même si l'array est bien modifiée... de même si on veut affecter c=b.concat(a.uniq()); sans le return this il y a un élément vide inséré dans la table après les éléments de b.
On est d'accord, c'est pourquoi je préfère ce genre de fonction :
On ne touche pas au tableau de départ et on a notre return
Ce n'est pas le comportement de la plupart des fonctions du prototype d'Array : sort() renvoie le tableau trié *et* le modifie, de même pour reverse()... Mais c'est un choix de conception.
Juste une petite correction au script :
Array.prototype.uniq=function (){ if(!this.length)return []; (J'avais zappé aussi ce return !)
[...] }
-- Y.D.
Le seul problème avec cet algo (performant) est que l'Array de
départ est modifiée, du coup le "return" se justifie moins et peut
même, à la limite, tromper son monde ! Pour ma part, j'enlèverais
cette dernière ligne...
Je m'étais dit la même chose que toi, mais sans cette ligne si on
écrit alert(a.uniq());
on a droit a un beau undefined, même si l'array est bien modifiée...
de même si on veut affecter c=b.concat(a.uniq()); sans le return this
il y a un élément vide inséré dans la table après les éléments de b.
On est d'accord, c'est pourquoi je préfère ce genre de fonction :
On ne touche pas au tableau de départ et on a notre return
Ce n'est pas le comportement de la plupart des fonctions du prototype
d'Array : sort() renvoie le tableau trié *et* le modifie, de même pour
reverse()... Mais c'est un choix de conception.
Juste une petite correction au script :
Array.prototype.uniq=function (){
if(!this.length)return [];
(J'avais zappé aussi ce return !)
Le seul problème avec cet algo (performant) est que l'Array de départ est modifiée, du coup le "return" se justifie moins et peut même, à la limite, tromper son monde ! Pour ma part, j'enlèverais cette dernière ligne...
Je m'étais dit la même chose que toi, mais sans cette ligne si on écrit alert(a.uniq()); on a droit a un beau undefined, même si l'array est bien modifiée... de même si on veut affecter c=b.concat(a.uniq()); sans le return this il y a un élément vide inséré dans la table après les éléments de b.
On est d'accord, c'est pourquoi je préfère ce genre de fonction :
On ne touche pas au tableau de départ et on a notre return
Ce n'est pas le comportement de la plupart des fonctions du prototype d'Array : sort() renvoie le tableau trié *et* le modifie, de même pour reverse()... Mais c'est un choix de conception.
Juste une petite correction au script :
Array.prototype.uniq=function (){ if(!this.length)return []; (J'avais zappé aussi ce return !)
[...] }
-- Y.D.
YD
Bonjour,
je reprends ta première réponse.
this.push(a.join());
C'est censé copier le contenu de a dans this ?
Oui, puisqu'on ne peut pas affecter à this...
Ça ne mettrait pas plutôt dans this un seul élément, qui serait la concaténation des valeurs de a séparées par des virgules ?
Oooooooops !
Remplacer par (pas trouvé moyen de faire ça d'un coup :-( ) : while(a.length)this.push(a.shift());
-- Y.D.
Bonjour,
je reprends ta première réponse.
this.push(a.join());
C'est censé copier le contenu de a dans this ?
Oui, puisqu'on ne peut pas affecter à this...
Ça ne mettrait pas plutôt
dans this un seul élément, qui serait la concaténation des valeurs de a
séparées par des virgules ?
Oooooooops !
Remplacer par (pas trouvé moyen de faire ça d'un coup :-( ) :
while(a.length)this.push(a.shift());
Ça ne mettrait pas plutôt dans this un seul élément, qui serait la concaténation des valeurs de a séparées par des virgules ?
Oooooooops !
Remplacer par (pas trouvé moyen de faire ça d'un coup :-( ) : while(a.length)this.push(a.shift());
-- Y.D.
Olivier Miakinen
Attention, si tu enlèves sort() de uniq(), uniq() aura un comportement pas forcément désiré sur un tableau non trié ! Enfin toi seul connais ton besoin...
C'est peut-être un comportement qui peut sembler curieux, mais c'est bien celui de la commande standard 'uniq' : http://unixhelp.ed.ac.uk/CGI/man-cgi?uniq
L'équivalent de 'sort' + 'uniq', c'est 'sort -u' : http://unixhelp.ed.ac.uk/CGI/man-cgi?sort
L'avantage de séparer les deux, c'est que si tu sais que le tableau est déjà trié tu n'as pas besoin de perdre du temps à le faire. Du coup, le comportement n'est pas si bizarre que ça : soit tu sais que le tableau est trié et tu utilises uniq() directement, soit tu n'en sais rien et tu le tries d'abord.
Sinon une fonction uniq() universelle c'est forcément plus lourd (algo qui va comparer le ième élément avec *tous* ses successeurs et si un (k) lui est égal --> splice(k,1) jusqu'à la fin de la chaîne, en vite fait :
Ok, mais alors il ne faut pas l'appeler uniq s'il existe une chance sur un million qu'un utilisateur Unix tombe dessus.
Attention, si tu enlèves sort() de uniq(), uniq() aura un comportement pas
forcément désiré sur un tableau non trié ! Enfin toi seul connais ton
besoin...
C'est peut-être un comportement qui peut sembler curieux, mais
c'est bien celui de la commande standard 'uniq' :
http://unixhelp.ed.ac.uk/CGI/man-cgi?uniq
L'équivalent de 'sort' + 'uniq', c'est 'sort -u' :
http://unixhelp.ed.ac.uk/CGI/man-cgi?sort
L'avantage de séparer les deux, c'est que si tu sais que le tableau est
déjà trié tu n'as pas besoin de perdre du temps à le faire. Du coup, le
comportement n'est pas si bizarre que ça : soit tu sais que le tableau
est trié et tu utilises uniq() directement, soit tu n'en sais rien et tu
le tries d'abord.
Sinon une fonction uniq() universelle c'est forcément plus lourd (algo qui
va comparer le ième élément avec *tous* ses successeurs et si un (k) lui
est égal --> splice(k,1) jusqu'à la fin de la chaîne, en vite fait :
Attention, si tu enlèves sort() de uniq(), uniq() aura un comportement pas forcément désiré sur un tableau non trié ! Enfin toi seul connais ton besoin...
C'est peut-être un comportement qui peut sembler curieux, mais c'est bien celui de la commande standard 'uniq' : http://unixhelp.ed.ac.uk/CGI/man-cgi?uniq
L'équivalent de 'sort' + 'uniq', c'est 'sort -u' : http://unixhelp.ed.ac.uk/CGI/man-cgi?sort
L'avantage de séparer les deux, c'est que si tu sais que le tableau est déjà trié tu n'as pas besoin de perdre du temps à le faire. Du coup, le comportement n'est pas si bizarre que ça : soit tu sais que le tableau est trié et tu utilises uniq() directement, soit tu n'en sais rien et tu le tries d'abord.
Sinon une fonction uniq() universelle c'est forcément plus lourd (algo qui va comparer le ième élément avec *tous* ses successeurs et si un (k) lui est égal --> splice(k,1) jusqu'à la fin de la chaîne, en vite fait :
Ok, mais alors il ne faut pas l'appeler uniq s'il existe une chance sur un million qu'un utilisateur Unix tombe dessus.
YD
C'est peut-être un comportement qui peut sembler curieux, mais c'est bien celui de la commande standard 'uniq' : http://unixhelp.ed.ac.uk/CGI/man-cgi?uniq
L'équivalent de 'sort' + 'uniq', c'est 'sort -u' : http://unixhelp.ed.ac.uk/CGI/man-cgi?sort
L'avantage de séparer les deux, c'est que si tu sais que le tableau est déjà trié tu n'as pas besoin de perdre du temps à le faire. Du coup, le comportement n'est pas si bizarre que ça : soit tu sais que le tableau est trié et tu utilises uniq() directement, soit tu n'en sais rien et tu le tries d'abord.
J'ai appris une commande nix ce soir -- et qui a un beau paquet d'options...
-- Y.D.
C'est peut-être un comportement qui peut sembler curieux, mais
c'est bien celui de la commande standard 'uniq' :
http://unixhelp.ed.ac.uk/CGI/man-cgi?uniq
L'équivalent de 'sort' + 'uniq', c'est 'sort -u' :
http://unixhelp.ed.ac.uk/CGI/man-cgi?sort
L'avantage de séparer les deux, c'est que si tu sais que le tableau est
déjà trié tu n'as pas besoin de perdre du temps à le faire. Du coup, le
comportement n'est pas si bizarre que ça : soit tu sais que le tableau
est trié et tu utilises uniq() directement, soit tu n'en sais rien et tu
le tries d'abord.
J'ai appris une commande nix ce soir -- et qui a un beau paquet d'options...
C'est peut-être un comportement qui peut sembler curieux, mais c'est bien celui de la commande standard 'uniq' : http://unixhelp.ed.ac.uk/CGI/man-cgi?uniq
L'équivalent de 'sort' + 'uniq', c'est 'sort -u' : http://unixhelp.ed.ac.uk/CGI/man-cgi?sort
L'avantage de séparer les deux, c'est que si tu sais que le tableau est déjà trié tu n'as pas besoin de perdre du temps à le faire. Du coup, le comportement n'est pas si bizarre que ça : soit tu sais que le tableau est trié et tu utilises uniq() directement, soit tu n'en sais rien et tu le tries d'abord.
J'ai appris une commande nix ce soir -- et qui a un beau paquet d'options...
-- Y.D.
Cenekemoi
Ce n'est pas le comportement de la plupart des fonctions du prototype d'Array : sort() renvoie le tableau trié *et* le modifie, de même pour reverse()...
Mea culpa, je n'avais pas fait attention à ce détail (qui n'en est pas un) ! Je retiendrais ce point...
... Mais c'est un choix de conception.
toutafé ;-)
-- Cordialement, Thierry
Ce n'est pas le comportement de la plupart des fonctions du prototype
d'Array : sort() renvoie le tableau trié *et* le modifie, de même pour
reverse()...
Mea culpa, je n'avais pas fait attention à ce détail (qui n'en est pas
un) ! Je retiendrais ce point...
Ce n'est pas le comportement de la plupart des fonctions du prototype d'Array : sort() renvoie le tableau trié *et* le modifie, de même pour reverse()...
Mea culpa, je n'avais pas fait attention à ce détail (qui n'en est pas un) ! Je retiendrais ce point...
... Mais c'est un choix de conception.
toutafé ;-)
-- Cordialement, Thierry
Cenekemoi
this.push(a.join()); C'est censé copier le contenu de a dans this ?
Pour copier une array "a" dans une autre "b" :
var b = a.concat();
(simple, précis, pas très clair)
(...) Remplacer par (pas trouvé moyen de faire ça d'un coup :-( ) : while(a.length)this.push(a.shift());
un peu lourd, non ?
-- Cordialement, Thierry ;-)
this.push(a.join());
C'est censé copier le contenu de a dans this ?
Pour copier une array "a" dans une autre "b" :
var b = a.concat();
(simple, précis, pas très clair)
(...)
Remplacer par (pas trouvé moyen de faire ça d'un coup :-( ) :
while(a.length)this.push(a.shift());
Très simple, mais on n'a pas le droit d'affecter à this, (sinon je me serais contenté de this=a...) !
-- Y.D.
Cenekemoi
Pour copier une array "a" dans une autre "b" :
var b = a.concat();
(simple, précis, pas très clair)
Très simple, mais on n'a pas le droit d'affecter à this, (sinon je me serais contenté de this=a...) !
Attention à ta dernière phrase : "this=a" ne représente pas du tout la même chose :
[1] var b = a.concat(); ==> COPIE a dans b [2] var b = a; ==> affecte la REFERENCE de a dans b
En d'autres termes, avec [1] j'ai bien DEUX objets, tandis qu'avec [2] j'ai deux références vers UN SEUL objet. Il suffit de modifier "b" pour s'apercevoir que "a" aussi est modifié dans ce dernier cas et pas dans le premier...
-- Cordialement, Thierry ;-)
Pour copier une array "a" dans une autre "b" :
var b = a.concat();
(simple, précis, pas très clair)
Très simple, mais on n'a pas le droit d'affecter à this,
(sinon je me serais contenté de this=a...) !
Attention à ta dernière phrase : "this=a" ne représente pas du tout la
même chose :
[1] var b = a.concat(); ==> COPIE a dans b
[2] var b = a; ==> affecte la REFERENCE de a dans b
En d'autres termes, avec [1] j'ai bien DEUX objets, tandis qu'avec [2]
j'ai deux références vers UN SEUL objet. Il suffit de modifier "b" pour
s'apercevoir que "a" aussi est modifié dans ce dernier cas et pas dans
le premier...
Très simple, mais on n'a pas le droit d'affecter à this, (sinon je me serais contenté de this=a...) !
Attention à ta dernière phrase : "this=a" ne représente pas du tout la même chose :
[1] var b = a.concat(); ==> COPIE a dans b [2] var b = a; ==> affecte la REFERENCE de a dans b
En d'autres termes, avec [1] j'ai bien DEUX objets, tandis qu'avec [2] j'ai deux références vers UN SEUL objet. Il suffit de modifier "b" pour s'apercevoir que "a" aussi est modifié dans ce dernier cas et pas dans le premier...
-- Cordialement, Thierry ;-)
YD
Très simple, mais on n'a pas le droit d'affecter à this, (sinon je me serais contenté de this=a...) !
Attention à ta dernière phrase : "this=a" ne représente pas du tout la même chose :
[1] var b = a.concat(); ==> COPIE a dans b [2] var b = a; ==> affecte la REFERENCE de a dans b
En d'autres termes, avec [1] j'ai bien DEUX objets, tandis qu'avec [2] j'ai deux références vers UN SEUL objet. Il suffit de modifier "b" pour s'apercevoir que "a" aussi est modifié dans ce dernier cas et pas dans le premier...
Entièrement d'accord, mais en l'occurrence a est une variable qui n'a d'existence que le temps d'exécution de la fonction et this = a affecterait (si c'était possible) la même référence qui n'existerait plus que pour l'objet désigné par this après l'exécution de la fonction. C'est vrai que pour le coup j'ai été un peu rapide et il est toujours bon de rappeler qu'en javascript l'affectation des objets se fait par référence et que, hormis les valeurs primitives (nombres, chaînes, null, true false) tout est objet.
Désolé pour ce fil, décousu pour cause de vacances ;-)
-- Y.D.
Très simple, mais on n'a pas le droit d'affecter à this,
(sinon je me serais contenté de this=a...) !
Attention à ta dernière phrase : "this=a" ne représente pas du tout la
même chose :
[1] var b = a.concat(); ==> COPIE a dans b
[2] var b = a; ==> affecte la REFERENCE de a dans b
En d'autres termes, avec [1] j'ai bien DEUX objets, tandis qu'avec [2]
j'ai deux références vers UN SEUL objet. Il suffit de modifier "b" pour
s'apercevoir que "a" aussi est modifié dans ce dernier cas et pas dans
le premier...
Entièrement d'accord, mais en l'occurrence a est une variable qui n'a
d'existence que le temps d'exécution de la fonction et this = a affecterait
(si c'était possible) la même référence qui n'existerait plus que pour
l'objet désigné par this après l'exécution de la fonction. C'est vrai que
pour le coup j'ai été un peu rapide et il est toujours bon de rappeler qu'en
javascript l'affectation des objets se fait par référence et que, hormis les
valeurs primitives (nombres, chaînes, null, true false) tout est objet.
Désolé pour ce fil, décousu pour cause de vacances ;-)
Très simple, mais on n'a pas le droit d'affecter à this, (sinon je me serais contenté de this=a...) !
Attention à ta dernière phrase : "this=a" ne représente pas du tout la même chose :
[1] var b = a.concat(); ==> COPIE a dans b [2] var b = a; ==> affecte la REFERENCE de a dans b
En d'autres termes, avec [1] j'ai bien DEUX objets, tandis qu'avec [2] j'ai deux références vers UN SEUL objet. Il suffit de modifier "b" pour s'apercevoir que "a" aussi est modifié dans ce dernier cas et pas dans le premier...
Entièrement d'accord, mais en l'occurrence a est une variable qui n'a d'existence que le temps d'exécution de la fonction et this = a affecterait (si c'était possible) la même référence qui n'existerait plus que pour l'objet désigné par this après l'exécution de la fonction. C'est vrai que pour le coup j'ai été un peu rapide et il est toujours bon de rappeler qu'en javascript l'affectation des objets se fait par référence et que, hormis les valeurs primitives (nombres, chaînes, null, true false) tout est objet.
Désolé pour ce fil, décousu pour cause de vacances ;-)