10
votes

Comment supprimer les valeurs dupliquées d'un tableau de coldfusion?

J'ai une fonction qui reçoit une chaîne de balises. Afin de sauvegarder les balises individuellement, la fonction transforme la chaîne en une matrice:

this.tags = listtoarray (this.tags, ",");

Comment puis-je supprimer des valeurs en double dans le cas où il y en a?


1 commentaires

Le type de données abstrait "défini", disponible en Java, est spécifiquement conçu pour résoudre ce genre de problème.


9 Réponses :


10
votes

Un moyen simple d'éliminer les doublons d'une liste consiste à convertir la liste en une structure d'abord, puis à convertir la structure en une matrice. Toutefois, si l'ordre des éléments de la liste est important, cela peut ne pas être approprié car les éléments de la structure seront triés.

Si l'ordre des éléments est important, vous devez construire la matrice manuellement plutôt que d'utiliser la fonction ListToArray. . P>

<!--- CF9 --->
<cfset tags = "apples,oranges,bananas,pears,APPLES" />
<cfset tagArray = arrayNew(1) />

<cfloop list="#tags#" index="tag" delimiters=",">
    <cfif not ArrayFindNoCase(tagArray,tag)>
        <cfset arrayAppend(tagArray, tag) />
    </cfif>
</cfloop>


0 commentaires

21
votes

J'aime utiliser Java pour ce type de tâche:

<cfset tags = "apples,oranges,bananas,pears,apples" />

<cfset tagsArray = createObject("java", "java.util.HashSet").init(ListToArray(tags)).toArray() />

<cfdump var="#tags#" />
<cfdump var="#tagsArray#" />


4 commentaires

Merci pour ça. Avez-vous fait des tests / connaissez-vous du haut de votre tête si cela est plus rapide que de boucler les valeurs dans une structure ColdFusion?


@MOHAMAD - d'un point de vue de la vitesse pure, je suppose que le hashset est plus rapide. Mais .. Sauf si vous avez affaire à d'énormes listes, les différences sont généralement petites. Je choisis habituellement la méthode qui fait le bon travail et que la vitesse ne concerne que la vitesse que si elle devient un problème.


La beauté de cette solution est qu'il faut une ligne! Dans mon cas, je devais savoir si un domaine particulier dans une requête de coldfusion avait plus d'une valeur unique. Tandis que d'autres solutions décrites ici auraient fonctionné, cette doublure a rendu mon code très simple: si (ArrayLen (CreateObject ("Java", "Java.Util.HashSet"). Init (Colname]). Toarray ( )) GT 1)


Jason, merci pour le code. Après avoir tiré des données d'un autre système, j'ai un éventail de structures en double. J'ai été capable de passer le tableau à travers le hashset et de vous retrouver avec un ensemble de matrices désespérées.



2
votes

Basé sur une idée de Jason Haritou, mais vous pouvez le faire dans Pure CF en utilisant la structure! (Les touches correspondant seront insensibles de cas) xxx

Cependant, pour les petites listes, je préfère la solution d'Antony.


1 commentaires

Juste curieux, pourquoi se soucier de la déclaration IF? Les structures n'autoriseront pas les valeurs en double, donc ne pas utiliser une condition un peu redondante ici?



0
votes

Il y a quelques UDF sur Cflib qui font cela, ArrayyDiff (http://www.cflib.org/udf/arraydiff) et ArrayCompare (http://www.cflib.org/udf/arrayCompare). < / p>

hth, Larry


0 commentaires

2
votes

J'ai juste dû désenciter une très grande liste (5k + entrées) et trouver un moyen beaucoup plus rapide que d'utiliser une boucle. Je ressens la nécessité de partager.

  1. Convertissez la liste en tableau (vous avez déjà une matrice, skip) code> li>
  2. Créer une requête avec QueryNew ("") code> li>
  3. Ajoutez une colonne à cette requête avec le tableau de STEP1 Code> LI>
  4. Query pour les valeurs distinctes sélectionner des éléments distincts de threquery cfquery> code> li>
  5. Convertir Résultat à la liste Code> Li>
  6. C'est une étape facile pour que vous puissiez reconvertir cette liste à un tableau LI> OL>

    J'ai écrit cela dans une fonction facile à utiliser: p>

    <cffunction name="deDupList" output="no" returntype="string">
        <cfargument name="thisList" required="yes">
        <cfargument name="thisDelimeter" required="yes" default=",">
        <cfset var loc = StructNew()>
    
        <cfset loc.thisArray = ListToArray(thisList,thisDelimeter)>
        <cfset loc.thisQuery = QueryNew("")>
        <cfset loc.temp = QueryAddColumn(loc.thisQuery,"items","varChar",loc.thisArray)>
        <cfquery name="qItems" dbtype="query">
            SELECT DISTINCT items FROM loc.thisQuery
        </cfquery>
        <cfset loc.returnString = ValueList(qItems.items)>
        <cfreturn loc.returnString>
    </cffunction>
    


3 commentaires

(Éditer) Je pouvais voir comment la boucle serait lente. Mais je suis très surprise que vous ayez dit que la méthode de Jason était lente, c'est-à-dire avec hashset . Il m'éclaircit vite pour moi avec plus de 10 000 articles. J'ai même triché et j'ai passé les résultats dans un vecteur pour rendre CF heureux.


J'ai foiré mon script de marquage bancaire lorsque je mettais la méthode de Jason, une erreur stupide. Vous avez raison, c'est assez rapide, corrigé mes résultats de marque de banc. Merci.


Merci. Je voudrais probablement aller avec hashset . Mais intéressant qu'un QOQ soit plus rapide que ce que j'aurais attendu.



1
votes

Il suffit de mettre le tableau dans une structure puis de le copier sur un tableau;)

http: // www.bennadel.com/blog/432-utilisateur-coldfusion-tructures-a-remove-dupliquer-list-values.htm


0 commentaires

1
votes

dans Coldfusion 10 ou Railo 4, vous pouvez utiliser Fonction UNIQ () de la soussecore.cfc : xxx

un avantage de uniq () est-il utile de passer une fonction de transformation, si nécessaire.

Note: j'ai écrit Soussecore.cfc


0 commentaires

6
votes

Étant donné que vous commencez vraiment par une chaîne / liste que vous convertissez ensuite en une matrice, vous pouvez transmettre la chaîne via LISTemoveDuplicate avant de la convertir en une matrice. Listremovedplicates a été introduit dans Coldfusion 10; Les paramètres d'entrée sont (liste, délimiter = ",", ignorécase = false). xxx

Si vous commencez par un tableau, vous auriez besoin de la convertir en une liste d'abord, puis retour après. xxx


3 commentaires

Les vidages de code ne sont pas des réponses. Veuillez éditer votre réponse et expliquer ce que ce code est, comment cela fonctionne et comment il répond à la question.


Je dirais que ce code parle de lui-même. Je viens de le lire et ce sera clair ce qui se passe.


Astuce: listremoveduplicates a été ajouté avec ColdFusion 10. N'essayez pas les versions antérieures.



2
votes

Prendre la réponse de Jason Juste un peu plus loin, voici une fonction arraydistinct code>.

function arrayDistinct (required array data) {
    var output = arrayNew(1);
    output.addAll(createObject("java", "java.util.HashSet").init(arguments.data));
    return output;
}


0 commentaires