0

I can be a bit confused sometimes between arrays and structures. However, I think I understand correctly now that my data below is technically an array of structures (correct me if I'm wrong):

<cfset Contacts = [
  {
    ID = "1",
    CompanyName = "Company One",
    FirstName = "Elliott",
    LastName = "Smith",
    ...etc...
  },
  {
    ID = "2",
    CompanyName = "Company Two",
    FirstName = "Matthew",
    LastName = "Ryan",
    ...etc...
  }
]>

I would like to search this data by ID (2, for example) and return the rest of that structure's data (CompanyName, FirstName, LastName, etc...).

How can I do this? (If my data is not in a searchable format, please let me know how I can change it so it is.)

Thank you!

12
  • I know it would be much easier if this data were in a database, but in this scenario I cannot do that. Commented Feb 26, 2014 at 19:22
  • 1
    Yes, it is an array of structures. AFAIK, the only way is to loop through the array elements and check the individual id values for a match. That said, if you need to access the elements by a specific key, then storing them in a structure might be better. (Unless you need to maintain a specific order) Commented Feb 26, 2014 at 19:33
  • 1
    If my data is not in a searchable format, please let me know how I can change it so it is. You could create your own query record set from the data. Then use SQL to run queries against it. livedocs.adobe.com/coldfusion/8/htmldocs/… Commented Feb 26, 2014 at 19:50
  • 1
    (Edit) @Michael - Use a nested structure. The syntax is essentially the same, just use the ids 1,2,... as the keys ie <cfset data = { firstKey = {ID=1, CompanyName="..."}, secondKey ={ID=2, CompanyName="..."} } />. Keep in mind you might store the data differently. For example, store it as JSON - then deserialize it when loaded into CF. Just be aware the file storage approach is not scalable... Out of curiosity, why can't you use a database for this? Commented Feb 26, 2014 at 20:34
  • 1
    You guys are gonna hate me. Not at all. The important part is you are on a much better path using the db route. Keep in mind, you can always use queryNew to mock up a db query in a pinch. BTW: Feel free to go with Mag's answer. Commented Feb 26, 2014 at 22:10

1 Answer 1

3

@Leigh's suggestion is a good one. Because you'll already have the data in memory at this point looping through an array even if it's pretty large will be fast. I like using CFScript for this type of task. Here's a working example using part of the data you provided:

<cfscript>
    // array of structs version
    contacts = [{
        ID = "1",
        CompanyName = "Company One",
        FirstName = "Elliott",
        LastName = "Smith"
    },{
        ID = "2",
        CompanyName = "Company Two",
        FirstName = "Matthew",
        LastName = "Ryan"
    }];

    for(i=1; i <= arrayLen(contacts); i++) {
        if (contacts[i]['id'] EQ '2') {
            writeoutput(contacts[i]['CompanyName'] & '<br />');
            writeoutput(contacts[i]['FirstName'] & '<br />');
            writeoutput(contacts[i]['LastName'] & '<br />');
            break;
        }
    }
</cfscript>

Update:

Here is another version using a struct of structs:

<cfscript>
    contact1 = {
        CompanyName = "Company One",
        FirstName = "Elliott",
        LastName = "Smith"
    };

    contact2 = {
        CompanyName = "Company Two",
        FirstName = "Matthew",
        LastName = "Ryan"
    };

    contacts = {
        1=contact1,
        2=contact2
    };

    contact_struct=structfind(contacts,'2');

    outstr = '';
    outstr = outstr & contact_struct['CompanyName'] & '<br />';
    outstr = outstr & contact_struct['FirstName'] & '<br />';
    outstr = outstr & contact_struct['LastName'] & '<br />';

    writeoutput(outstr);

</cfscript>
Sign up to request clarification or add additional context in comments.

4 Comments

Actually based on later comments, I think a structure of structures would be better in this case. Then there is no need for looping. Just a simple lookup by key. (Small tip: unless the array can contain duplicate id's, you typically want to break; out of the for loop once a matching value is found, since there is nothing more to do.)
OK added a second example with a struct of structs version and added break; to the first. I'll be curious to know what works out!
Thank you! Very helpful to see it in an example.
I usually go with <cfif structKeyExists(...)>, then grab the value with structure notation. Just to avoid the exception thrown by structFind if the key does not exist for some reason. Just personal preference though :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.