My situation:
I have two lists in NetLogo which are thought to correspond with each other, e.g. being two rows of of a matrix.
For example
set list-1 [1 2 2]
set list-2 [13 7 8]
where 1 is thought to be paired with 13, 2 with 7, and 2 with 8. These pairings may not be broken.
My problem:
I want to filter list-2 by applying a criterion on the corresponding elements of list-1. E.g. preserve an item of list-2 if the corresponding item equals 2
The result should be:
list-2: [7 8]
where the 13 is removed because the corresponding 1 does not equal 2.
How to program that in NetLogo?
My NetLogo version: 5.3.1
I can think of many different ways to do this:
to go
let list-1 [1 2 2]
let list-2 [13 7 8]
; the most straightforward, imperative way:
let list-3 []
(foreach list-1 list-2 [
if ?1 = 2 [ set list-3 lput ?2 list-3 ]
])
print list-3
; an uglier imperative version using indices:
let list-4 []
let i 0
while [ i < length list-1 ] [
if item i list-1 = 2 [ set list-4 lput item i list-2 list-4 ]
set i i + 1
]
print list-4
; using reduce, sentence and map:
print reduce sentence (map [
ifelse-value (?1 = 2) [ ?2 ] [ [] ]
] list-1 list-2)
; using map, filter, and indices:
print map [ item ? list-2 ] filter [
item ? list-1 = 2
] n-values length list-1 [ ? ]
; another variant using `filter`:
print map last filter [ first ? = 2 ] (map list list-1 list-2)
end
That last one is by far my favorite, as I think it expresses the intent better than the others, but that might be subjective.
To make things reusable, you can isolate your preferred method in a reporter:
to-report filtered-by-first-list [ filtering-task list-1 list-2 ]
report map last filter [
(runresult filtering-task first ?)
] (map list list-1 list-2)
end
And then you can call it like this:
observer> show filtered-by-first-list task [ ? = 2 ] [1 2 2] [13 7 8]
observer: [7 8]
Converting all of this to NetLogo 6 syntax is left as an exercise to the reader. :-)