Eliminare duplicati da una lista e ordinarla

  • 12
  • Mar 2012
  • Dev @ Contech Lab
  • View: 31139 | 0 Comments

  • coldfusion | list | array | cfc

  • Mi è capitato spesse volte di avere una lista di valori, numerici o alfanumerici, e dover eliminare i duplicati.

    Tra i vari tentativi, ho scritto codice per eseguire loop in array, creazione di query con successivi loop e ordinamenti, assegnazioni in variabili.

    La strada più veloce che ho trovato di recente è quella di utilizzare una struttura.

    La struttura infatti di default non accetta duplicati. Vediamo come.

    view plain print about
    <!--- // 
    Supponiamo di avere una lista di valori del tipo seguente:
    Definizione della lista di prova 
    // --->


    <cfset miaLista = "coldfusion,ajax,coldfusion,bit,byte,bit">

    con il seguente semplice codice è possibile creare una struttura priva di duplicati e successivamente ordinarla in modo alfabetico.

    Si deve tenere presente che la struttura per sua definizione non permette la creazione di duplicati e quindi porta direttamente alla soluzione del problema

    view plain print about
    <!--- 
    crea struttura vuota per ospitare i nostri dati non duplicati
    --->

    <cfset TempStruct = {} />   

    <cfloop list="#miaLista#" index="i">

    <!--- 
    popola e toglie duplicati in quanto la 
    struttura non ammette duplicati :) 
    --->


       <cfset TempStruct[i] = i />

    </cfloop>

    <!--- 
    al termine del loop esegue ordinamento alfabetico  
    --->

    <cfset Array_Tags = StructSort(TempStruct, 'text', 'asc')>

    La logica di ordinamento termina qui. E' la strada più breve che ho trovato al momento.

    Se vogliamo ottimizzare il codice e renderlo disponibile al riuso è necessario registrarlo nei componenti e quindi creare una nuova funzione. Tale funzione, che sarà registrata in un file .cfc, eseguirà una query sul mio database, leggerà i valori da una query, eseguirà il codice di pulizia dei duplicati per restituire la lista dei valori ordinati in alfabetico creascente. Vediamo come.

    view plain print about
    <cfcomponent output="false">
    <cffunction name="getMyBlogTags" access="public" returntype="array" 
    output="false" hint="Seleziona Tags, elimina duplicati e ordina">

            
    <cfargument name="id_cat" type="numeric" 
     default="0" required="false">

    <cfargument name="maxrows" type="numeric" 
    default="50" required="false">


    <cfquery name="sel_tags" datasource="#request.datasource#" 
      maxrows=#maxrows#>

    SELECT   distinct tags, visite FROM MyCms_doc
    WHERE    0=0
    and id_cat = <cfqueryparam value="#id_cat#" cfsqltype="CF_SQL_INTEGER">
    AND tags IS NOT NULL
    order by visite desc
    </cfquery>

    <!--- 
    crea struttura 
    --->

    <cfset TempStruct = {} />

    <!---
    esegue un ciclo di loop sugli elementi estratti dalla query
    si tenga presente che gli elementi per ogni record sono di questo tipo:
    rec1: coldfusion,jquery
    rec2: jquery,coldfusion,bit,byte
    rec3: bit,jequery

    quindi il valuelist concatena gli elementi arrivando a questo:
    coldfusion,jquery,jquery,coldfusion,bit,byte,bit,jequery
    --->



    <cfloop list="#valuelist(sel_tags.tags)#" index="i">

       <!--- 
       popola e toglie duplicati in quanto la stru non ammette duplicati :) 
       --->

       <cfset TempStruct[i] = i />
    </cfloop>

    <!--- 
    esegue ordinamento 
    --->

    <cfset Array_Tags = StructSort(TempStruct, 'text', 'asc')>
                    
    <!---
    ritorna un Array senza duplicati e correttamente ordinato
    --->

       <cfreturn Array_Tags>
    </cffunction>
    </cfcomponent>

    Il componente visto sopra, è quello utilizzato in questo Blog per mostrare i Termini Cloud. Per utilizzare la funzione è sufficiente fare un Invoke del componente oppure referenziarlo come oggetto di memoria nel seguente modo:

    view plain print about
    <!--- 
    Chiama il componente e memorizza l'array risultato
    --->

    <cfset Blog_Tags        = application.componenti.getMyBlogTags(id_cat='2',maxrows='20')>

    <!--- 
    A questo punto esegue un semplice output dell'array 
    --->



    <cfloop array="#Blog_Tags#" index="tag">
       <cfoutput>
       <a href="MioLink_To">#tag#</a>
       </cfoutput>
    </cfloop>

    Fine. Attendo commenti