Search code examples
listdictionaryif-statementcommandnetlogo

Is there a way to use an if statement inside a map procedure?


I want to update several values in a list called list1 depending on the values in two other lists called list2 and list3. Basically the values in list2 determine which equation the model should use to update the values in list1 and the values in list3 are used in those equations.

A working example would be:

turtles-own [list1 list2 list3]

to setup
  clear-all
  setup_turtles
  reset-ticks
end

to setup_turtles
  create-turtles 10
  [
    set list1 n-values 20 [1]
    set list2 n-values 20 [0 + random 3]
    set list3 n-values 20 [-0.5 + random-float 1]
  ]
end

to go
  ask turtles[ update_list1 ]
  tick
end

to update_list1
  set list1 (map [[b c] ->
    if (b = 0) [ 1 + c ]
    if (b = 1) [ 1 - c ]
    if (b = 2) [ 1 - c / 2 ]
  ] list2 list3)
end

Netlogo tells me it expects a command within the if statement, which makes sense considering how the if function is built. I was wondering if they're is a workaround which could make that work.

I have tried to use the ifelse-value function instead of if in the update_list1 procedure and it works (see code below)

to update_list1
  set list1 (map [[b c] ->
    ifelse-value (b = 0) [ 1 + c ] [
      ifelse-value (b = 1) [ 1 - c ][
        1 - c / 2
      ] 
    ] 
  ] list2 list3)
end

However, later on I plan on having more than 3 different values in list2 and I would like to avoid multiple indentation resulting from calling ifelse-value several times in a row.


Solution

  • Netlogo has the option to use more than one boolean for a single call of ifelse or ifelse-value. To do this, you need to put round brackets around the entire expression: (ifelse-value boolean1 [ reporter1 ] boolean2 [ reporter2 ] ... [ elsereporter ]). This ensures that you don't have to work with nested ifelse-value's

    to update_list1
      set list1 (map [[b c] ->
        (ifelse-value
            b = 0 [ 1 + c ]
            b = 1 [ 1 - c ]
            b = 2 [1 - c / 2]
                  [print "b is not one of the expected values"]
        ) 
      ] list2 list3)
    end