Skip to main content
Participant
October 27, 2025
Answered

Unexpected behavior when indexing struct with dynamic keys in

  • October 27, 2025
  • 1 reply
  • 102 views

Hi,
I came across something odd while working with ColdFusion 2021 . I have an array of structs representing student data and I'm trying to build a nested struct using arrayEach. Here's the code:

<cfscript>
    arrayData = [
      {
        "name": "Aisha Khan",
        "age": 21,
        "major": "Computer Science",
        "gpa": 3.5,
        "hobbies": ["coding", "chess", "hiking"]
      },
      {
        "name": "Liam Patel",
        "age": 28,
        "major": "Economics",
        "gpa": 3.5,
        "hobbies": ["debating", "football", "photography"]
      },
      {
        "name": "Sofia Zhang",
        "age": 20,
        "major": "Psychology",
        "gpa": 3.5,
        "hobbies": ["reading", "painting", "yoga"]
      },
      {
        "name": "Noah Smith",
        "age": 23,
        "major": "Mechanical Engineering",
        "gpa": 3.2,
        "hobbies": ["robotics", "gaming", "cycling"]
      },
      {
        "name": "Fatima Yusuf",
        "age": 21,
        "major": "Business Administration",
        "gpa": 3.8,
        "hobbies": ["blogging", "traveling", "baking"]
      }
    ]
    
    testStruct = {};
   arrayEach(arrayData, function(row) {
        testStruct[row.gpa][row.age] = row.name;
    });
    writedump(testStruct);
</cfscript>


I expected this to throw an error because testStruct[row.gpa] would be undefined the first time it's accessed however the structure is created and the code runs fine.

Is this expected behaviour in coldfusion? Or is there something else which is going on under the hood?

Many Thanks

    Correct answer BKBK

    Yes, that is expected behaviour.

    In your code, "row" is the name of the argument of the closure function. This argument is a dummy, a place-holder variable. It represents each array item. So it will exist if the array has at least 1 item.

    Then, since row.gpa, row.age and row.name are defined, the line

    testStruct[row.gpa][row.age] = row.name;

    is an assignment statement. It populates the struct. 

     

    This becomes clearer  when you rewrite the code as follows:

    testStruct = {};
    myClosure=function(row) {
        var currentGpa=row.gpa;
        var currentAge=row.age;
        var currentName=row.name;
        testStruct[currentGpa][currentAge] = currentName;
    };
    arrayEach(arrayData, myClosure);
    writedump(testStruct);

    However, you will get an error if testStruct[row.gpa] is used on the right-hand-side of "=" in an assignment statement.

    1 reply

    BKBK
    Community Expert
    BKBKCommunity ExpertCorrect answer
    Community Expert
    October 28, 2025

    Yes, that is expected behaviour.

    In your code, "row" is the name of the argument of the closure function. This argument is a dummy, a place-holder variable. It represents each array item. So it will exist if the array has at least 1 item.

    Then, since row.gpa, row.age and row.name are defined, the line

    testStruct[row.gpa][row.age] = row.name;

    is an assignment statement. It populates the struct. 

     

    This becomes clearer  when you rewrite the code as follows:

    testStruct = {};
    myClosure=function(row) {
        var currentGpa=row.gpa;
        var currentAge=row.age;
        var currentName=row.name;
        testStruct[currentGpa][currentAge] = currentName;
    };
    arrayEach(arrayData, myClosure);
    writedump(testStruct);

    However, you will get an error if testStruct[row.gpa] is used on the right-hand-side of "=" in an assignment statement.