Convert strings to variable name in Netlogo

Viewed 128

I was trying to update a bunch of global variables using the set command.

The global variables are the combinations of different strings.

For example, I have 6 global variables called:

a_x, b_x, c_x, a_y, b_y, c_y

I want to update the values of all six global variables into 1 using the foreach command.

Below is my code:

let a_x 0
let b_x 0
let c_x 0
let a_y 0
let b_y 0
let c_y 0

let first_list (list "a" "b" "c")
let second_list (list "x" "y")

foreach first_list [
   [i] -> 
   foreach second_list [
     [j] -> 
   set (word i "_" j) 1
 ]
]

I got the "This isn't something you can use "set" on" error message.

I guess I may need to convert the strings (word i "_" j) into a variable name so that the Netlogo can update it by the set command.

Is there any way that I can convert the strings into a variable name in the foreach loop in Netlogo?

2 Answers

You can use the run primitive on a string to execute NetLogo code that you build from strings. You can use that to set global variables. Instead of constructing just the variable name with word, you can construct the whole set a_x 1 statement, then run that.

This does not work with local let variables, however, due to the way run handles scope when used with string values.

So here is your sample updated with globals that will work:

globals [
  a_x
  b_x 
  c_x
  a_y
  b_y
  c_y
]

to test
  clear-globals ; reset to `0`
  
  let first_list (list "a" "b" "c")
  let second_list (list "x" "y")

  foreach first_list [
    [i] -> foreach second_list [
      [j] -> run (word "set " i "_" j " " 1)
    ]
  ]
  
  show a_x ; outputs `1`
end

Edit to add a second option.

You can also use the table extension instead to store the values. It can use strings as keys (your variable names), and store whatever values you like. Depending on your use case, this might overall wind up easier/simpler.

I'm afraid you can't do that. You are trying to treat a string holding the name of a variable as the variable, which does not work.

Perhaps the closest you can get is this, assuming a_x b_x c_x ... are already defined as global or local variables:

 let list-of-variables (list
   a_x
   b_x
   c_x
   ... )

 foreach list-of-variables [ next-variable -> set next-variable 1 ]
Related