Группировка списков по элементам в Netlogo - PullRequest
0 голосов
/ 05 марта 2019

Допустим, у меня есть модель в 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, что делает свое дело, но а) это невероятно грязно, б) требует, чтобы я заранее знал длину списка, чего в действительности не знаю (это процедура черепахи) и в) это кажется большим количеством ненужного кодирования.

Существует ли какой-либо способ расширить описанную выше процедуру на любое количество начальных элементов (возможно, внутри цикла while?) И не требует создания списка для каждого начального элемента списка?

Большое спасибо

1 Ответ

2 голосов
/ 05 марта 2019

Я предполагаю, что желаемый результат должен быть: [[["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 listoflists [ l -> first l ]
...