2009-05-14 12 views
12

J'ai un tableau multidimensionnel semi-volumineux (centaines d'enregistrements) dans ColdFusion. Chaque élément du tableau est une structure avec plusieurs propriétés. Je veux rechercher dans le tableau une structure qui a une propriété "name" spécifique. Je sais que pour un tableau de valeurs de chaîne que je pourrais utiliser des méthodes Java comme ceci:ColdFusion - Quel est un moyen efficace de rechercher un tableau de structures?

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

... mais ça ne marchera pas pour un tableau de struct. Je sais aussi que je pourrais le forcer comme ceci:

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

... mais je pense qu'il doit y avoir un moyen plus efficace. Est-ce que quelqu'un a une meilleure solution que celle-ci? Vous pouvez supposer que la propriété "name" est présente dans chaque structure et qu'il n'y a aucun espace ou aucun autre objet dans le tableau.

Répondre

11

Sauf si vous avez une table de hachage vous créez que vous construisez le tableau, je ne Ne voyez pas comment vous allez créer une fonction de recherche plus rapide que la solution O (n) que vous avez publiée. Quoi qu'il en soit, pendant que vous construisez vos tableaux, vous pouvez faire quelque chose comme ceci:

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

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

Cela suppose que la valeur existe toujours. Vous devrez peut-être vérifier StructKeyExists (nameValues, "WhatImLookingFor") avant de passer l'appel.

+0

C'est une bonne idée! Je vais utiliser ça dans le futur. –

1

Sans regarder trop profondément, j'envisager de convertir la structure à une requête (ci-dessous) et faire ensuite faire requête d'une requête .. en supposant que votre jeu de données n'est pas trop énorme!

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

partagent ce que vous avez fini de faire!

Editer: Le StructFindValue suggéré semble être excellent aussi, je ne pensais pas à rechercher des fonctions pertinentes.

0

CFGroovy FTW! :)

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

ou .. si vous voulez un style plus java (w/o fermeture)

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

Cette solution est-elle meilleure que l'algorithme original affiché dans la question? Je ne suis pas encore bien sur Groovy (ou CFGroovy), mais il * semble * que vous venez de réécrire le même algorithme dans une autre langue. Pour ce que ça vaut, c'est un peu plus lisible, et sans doute plus élégant ... mais ses chances d'être plus rapide sont (sans doute) minces, étant donné qu'il doit exécuter Groovy pour fonctionner, et retourner à CF. Je suppose que si c'est beaucoup plus rapide dans Groovy, alors il est possible que les frais généraux en valent la peine, mais j'en doute. –

5

Dans CF 10 ou Railo 4, vous pouvez utiliser:

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

Il n'est pas documenté, mais ça marche! ArrayFindAll() est également une option si vous voulez tous les indices.

+0

Cette classe de nouvelles fonctions est géniale. – rhinds