#list #foreach #netlogo
#Список #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, что делает свое дело, но а) это невероятно запутанно, б) требует, чтобы я заранее знал длину списка, чего у меня нет в реальном случае (это черепашья процедура) и в) кажется, что это много ненужного кодирования.
Есть ли какой-либо способ распространить описанную выше процедуру на любое количество начальных элементов (возможно, внутри цикла while?) и не требует создания списка для каждого начального элемента списка?
Большое спасибо
Ответ №1:
Я предполагаю, что желаемый результат должен быть: [[["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 из расширения table.
table:group-items listoflists [ l -> first l ]
Комментарии:
1. Отлично! Большое спасибо, Брайан. Будет использовать расширение таблицы для минимизации кода (нужно сделать это для нескольких типов агентов …) работает просто великолепно! 🙂
2. И да, действительно, мне не хватало квадратной скобки, хорошо заметной.