NetLogo:如何使用引用相应列表的标准来过滤列表?

NetLogo: How to filter a list using a criterion which refers on a corresponding list?

我的情况: 我在 NetLogo 中有两个列表,它们被认为是相互对应的,例如是矩阵的两行。

例如

set list-1 [1 2 2]
set list-2 [13 7 8]

其中 1 被认为与 13 配对,2 与 7 配对,2 与 8 配对。这些配对可能不会被破坏。

我的问题:

我想通过对 list-1 的相应元素应用条件来过滤 list-2。例如。如果相应的项目等于 2

,则保留 list-2 的项目

结果应该是:

list-2: [7 8]

去掉13是因为对应的1不等于2

如何在 NetLogo 中编程?

我的 NetLogo 版本:5.3.1

我可以想到很多不同的方法来做到这一点:

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

最后一个是我最喜欢的,因为我认为它比其他的更能表达意图,但这可能是主观的。

为了使事情可重用,您可以在报告器中隔离您的首选方法:

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

然后你可以这样称呼它:

observer> show filtered-by-first-list task [ ? = 2 ] [1 2 2] [13 7 8]
observer: [7 8]

将所有这些转换为 NetLogo 6 语法留给 reader 作为练习。 :-)