2009-05-14 9 views
12

Ho un array unidimensionale semi-grande (centinaia di record) in ColdFusion. Ogni elemento nell'array è una struttura con diverse proprietà. Voglio cercare nell'array una struttura che abbia una specifica proprietà "nome". So che per una serie di valori di stringa ho potuto utilizzare metodi Java in questo modo:ColdFusion - Qual è un modo efficiente per cercare una serie di strutture?

<cfset arrayIndex = myArray.indexOf("WhatImLookingFor") + 1> 

... ma che non funziona per una vasta gamma di strutture. So anche che potrei forza bruta in questo modo:

<cfset arrayIndex = 0> 
<cfloop from="1" to="#ArrayLen(myArray)#" index="counter"> 
    <cfif myArray[counter].name IS "WhatImLookingFor"> 
     <cfset arrayIndex = counter> 
    </cfif> 
</cfloop> 

... ma mi sento come se ci deve essere un modo più efficiente. Qualcuno ha una soluzione migliore di questa? Si può presumere che la proprietà "name" sia presente in ogni struct e che non ci siano spazi vuoti o altri oggetti nell'array.

risposta

11

Se non avete una tabella hash che si sta creando, come si costruisce la matrice, io don vediamo come creerai una funzione di ricerca più veloce della soluzione O (n) che hai pubblicato. Ad ogni modo, mentre si stanno costruendo gli array, si potrebbe fare qualcosa di simile:

<cfloop query="qryValues"> 
    <cfset nameValues[name] = currentrow /> 
    <cfset myArray[currentrow].name = name /> 
</cfloop> 

<cfset arrayIndex = nameValues["WhatImLookingFor"] /> 

Questo presuppone che il valore esiste sempre. Potrebbe essere necessario selezionare StructKeyExists (nameValues, "WhatImLookingFor") prima di effettuare la chiamata.

+0

Questa è una buona idea! Lo userò in futuro. –

1

Senza guardare troppo in profondità, vorrei prendere in considerazione la conversione della struttura a una query (sotto) e poi facendo fare un query di una query .. assumendo che il set di dati non sia troppo grande!

http://www.bennadel.com/blog/264-Ask-Ben-Converting-A-Struct-To-A-Query-And-More-Java-.htm

condivido quello che ha finito per fare!

Modifica: Anche l'aspetto di StructFindValue sembra eccellente, non ho pensato di cercare alcuna funzione pertinente.

0

CFGroovy FTW! :)

<cfset count = 0> 
<g:script> 
count = myArray.find({ 
    it["NAME"] == "WhatImLookingFor" } 
}) 
</g:script> 

o .. se vi piace un più stile java (w/o chiusura)

<cfset count = 0> 
<g:script> 
for (i in myArray) { 
    if(i["NAME"] == "WhatImLookingFor") 
    count++ 
} 
</g:script> 
+1

Questa soluzione è migliore dell'algoritmo originale pubblicato nella domanda? Non ho ancora letto bene Groovy (o CFGroovy), ma * sembra * che tu abbia appena riscritto lo stesso algoritmo in un'altra lingua. Per quello che vale, è leggermente più leggibile, e probabilmente più elegante ... ma le probabilità di essere più veloci sono (probabilmente) da zero a zero, considerando che deve passare a Groovy per essere eseguito, e tornare alla CF. Suppongo che se a Groovy sia tremendamente più veloce, è possibile che ne valga la pena, ma ne dubito. –

5

In CF 10 o Railo 4, è possibile utilizzare:

arrayIndex = ArrayFind(arrayOfStructs, function(struct){ 
    return struct.name == "WhatImLookingFor"; 
}); 

non è documentato, ma funziona! ArrayFindAll() è anche un'opzione se vuoi tutti gli indici.

+0

Questa classe di nuove funzioni è eccezionale. – rhinds

Problemi correlati