Multi dimensional arrays (Square Bracket Syntax)

As a new developer for Choicescript it took ages to find documentation on arrays. I finally found this:

So I did lots of experimenting and found out some useful stuff (ancient software dveloper here, started in the 1970s.)

Part 1 is just what it tells you in the wikky, that square brackets append their content (with a leading underscore) onto the variable name to produce the final variable name for the script to work with.

So given:
*create fairy_1 “Beth”
*create fairy_2 “Slavos”

Then this code:
*temp fairy_id 2
${fairy[fairy_id]}

Will be interpreted as:
${fairy_2}

And the output will be:
Slavos

Ok, cool. The elements are static but there is a dynamic reference. So what about 2d arrays? I tried this:

*create fairy_1 “Beth”
*create fairy_2 “Slavos”
*create fairy_3 “Lissa”

*create fairy_type_1 “nice”
*create fairy_type_2 “naughty”
*create fairy_type_3 “nice”

*greeting_behavior_nice “Oh, so pleased to meet you.”
*greeting_behavior_naughty “Wadda you want?”

And I want the type of a fairy to tell me the behavior given a fairy ID. In other languages this could be handled by a 2D array of the form x[a][b]. But that is not how choicescript does things. It took a few experiments and I found this does the trick:

Fairy ${fairy[fairy_id]} sees you and says “{greeting_behavior[fairy_type[fairy_id]]}”

In other words, the structure is x[a[b]]

So with a fairy ID of 3, then
greeting_behavior[fairy_type[fairy_id]]
becomes greeting_behavior[fairy_type_3]
which becomes greeting_behavior_nice which results in:

Fairy Lissa sees you and says “Oh, so pleased to meet you.”

A 3d array would look like this x[a[b[c]]], and so on to whatever depth you need. I’m not sure how deep these substitutions can nest, but two was enough for my purposes.

If someone would like to verify this, and then update the wiki to include this it would be cool.
If someone is able to anoint me with wiki update powers I would be happy to do it myself once at least one other person has verified my work. I have a long history of good wikki gardening techniques.

4 Likes

I don’t know about wiki, but that sounds useful! Thanks for the experimentation.

I have edit access at the wiki now.
So if someone will double check my work and let me know then I will go and update.

1 Like

I’ll try and check it in the next day or so.

Are you aware of the cslib project?

It contains a number of extremely useful libraries including cslib_array, which will likely have a easier solution. You may care to check it out.

You could also solve your particular problem via cslib using cslib_object, which simulates an array of objects.

e.g.
Step 1: define your fairy ‘object’

*create fairy_field_1 “name”
*create fairy_field_2 “type”
*create fairy_field_3 “greeting”
*create fairy_field_max 3

Step 2: create a place to hold the current fairy instance

*create fairy_name “”
*create fairy_type “”
*create fairy_greeting “”

Step 3: create some fairies

*create fairy_1_name “Beth”
*create fairy_1_type “nice”
*create fairy_1_greeting “Oh, so pleased to meet you.”

*create fairy_2_name “Slavos”
*create fairy_2_type “naughty”
*create fairy_2_greeting “Wadda you want?”

etc

Step 4: get your fairy e.g.
*gosub_scene cslib_object get fairy 2

fairy_name will now be “Slavos”
fairy_type will now be “naughty”
fairy_greeting will now be “Wadda you want?”

You can also get it by any field:
*gosub_scene cslib_object get_by_field fairy “name” “Slavos”
which will have the same effect.

4 Likes

Your code is definitely right, but I want to discuss the terminology a little because it can be rather confusing, and the wiki should not be confusing.

The “array” syntax in ChoiceScript is actually more akin to Objects or Dictionaries in other programming languages. I talk a little more about that here:

This is especially true when you’re using “attributes” (string-based indexes). In essence what you have there are not 2D arrays, they are 1D arrays that contain objects with attributes.

Take a look at the following examples (I’ve modified your code a little, just to make the comparison clearer, but the syntactical requirements remain the same).

Python-esque Language

fairies = [
  { 'name': "Beth", 'type': "nice" },
  { 'name': "Slavos", 'type': "naughty" },
  { 'name': "Lissa", 'type': "nice" },
]

greeting_behavior = {
  'nice': "Oh, so pleased to meet you.",
  'naughy': "Wadda you want?"
}

fairies[0]["name"] == "Beth"
greeting_behavior['fairies[0]['type']] == "Oh, so pleased to meet you"

ChoiceScript

*create fairy_0_name "Beth"
*create fairy_1_name "Slavos"
*create fairy_2_name "Lissa"

*create fairy_0_type "nice"
*create fairy_1_type "naughty"
*create fairy_2_type "nice"

*create greeting_behavior_nice "Oh, so pleased to meet you."
*create greeting_behavior_naughty "Wadda you want?"

${fairy[0]["name"]} == "Beth"
${greeting_behavior[fairy[0]["type"]]} == "Oh, so pleased to meet you"

If we remove the dereference (${}) brackets, you’ll see they actually look remarkably similar:

fairies[0]["name"] == "Beth"
greeting_behavior[fairies[0]['type']] == "Oh, so pleased to meet you"

fairy[0]["name"] == "Beth"
greeting_behavior[fairy[0]["type"]] == "Oh, so pleased to meet you"

A proper 2D array would look something more like:

fairies = [
  [ 'Beth', 'nice' ]
  [ 'Slavos', 'naughty' ]
  [ 'Lissa', 'nice' ]
]

fairies[0][0] == "Beth"
fairies[0][1] == "nice"

*create fairy_1_1 "Beth"
*create fairy_1_2 "Slavos"
*create fairy_1_3 "Lissa"
*create fairy_2_1 "nice"
*create fairy_2_2 "naughty"
*create fairy_2_3 "nice"

fairy[1][1] == "Beth"
fairy[1][2] == "nice"

(More useful example might be):

fairy[fairy_id][attr_id]

Which is what what you’d expect from a standard language’s syntax.

tl;dr Your example is right, but you’re treating things more as objects than arrays, so using the term 2D arrays (and saying it’s different in other languages) is a little misleading.

5 Likes

Thanks Stephen and CJW.
So my experiments had a mistake which is elucidated by your answers. I did not think Choicescript allowed the form a[b][c], which would produce variable a_b_c. My early experiments must have had an error because that didn’t seem to work. I confirmed that it is possible by running this code.

*temp a_1_2_3 0
*temp b 1
*temp c 2
*temp d 3
${a[b][c][d]}

Which indeed produces 0 as the text on screen.

Regarding naming of the article. One problem to address is that people used to other languages will be looking for arrays, multi dimension array, objects, structures and so on. How to give them a clue that this article solves the problem they want addressed?

Would you have a properly named article and then others like “Multidimensional Arrays” that explain the main article is what the coder really wants to look at? This is an old wiki problem about singular titles and multiple ways of identifying the same content, not all of which are known to all readers.

2 Likes

I’d keep the primary page called arrays, but have a section for multidimensional arrays, with further subsections for “objects” and numerical index (traditional) multidimensional arrays.

We can add alias page names too, if you feel that would help.

3 Likes