按Netlogo中的元素对列表进行分组

时间:2019-03-05 18:51:29

标签: list foreach netlogo

让我们说我在Netlogo中有一个模型,现在对开发一个按第一个元素分组列表的报告程序/过程感兴趣。 举例来说,

globals[list1 list2 list3 listoflists
ordered-list-a
  ordered-list-b
]

to setup
  set list1 ["a" "b" "c"]
  set list2 ["a" "c" "d"]
  set list3 ["b" "a" "c"]
  set listoflists (list list1 list2 list3)
end

我想创建一个列表列表,以便在每个列表中都有以相同元素开头的列表。因此,所需的输出是

[[["a" "b" "c"]["a" "c" "d"]]["b" "a" "c"]]]

即,第一个元素将所有列表以a放在首位,第二个元素以“ b”开头。

理想情况下,这应该可以大量扩展。我尝试过

to create-list
  set ordered-list-a []
  set ordered-list-b []
   (foreach listoflists [[i] ->
    if item 0 i = "a" [set ordered-list-a lput i ordered-list-a]
  if item 0 i = "b" [set ordered-list-b lput i ordered-list-b]
  ])  
end

,然后从a和b创建一个列表,就可以了,但是a)令人难以置信的混乱,b)要求我事先知道列表的长度,在实际情况下我不知道(这是a乌龟程序)和c)似乎有很多不必要的编码。

是否可以通过某种方式将上述过程扩展到任意数量的起始元素(也许在while循环内?),并且不需要为每个初始列表元素创建一个列表?

非常感谢

1 个答案:

答案 0 :(得分:2)

我假设期望的输出应该是:[[["a" "b" "c"]["a" "c" "d"]][["b" "a" "c"]]]。我相信您在第二小组之前错过了[

无论如何,一种简单但效率不高的方法是:

; items is a list of items to be grouped
; key is an anonymous reporter that extracts the group label from a single item
to-report group-by [ items key ]
  let keys remove-duplicates map key items
  report map [ k -> filter [ x -> (runresult key x) = k ] items ] keys
end

请注意,以上内容是完全概括的分组功能。要在您的情况下使用它,您可以这样做:

group-by listoflists [ l -> first l ]

一种更有效的方法是使用table:group-items reporter from the table extension

table:group-items listoflists [ l -> first l ]