NetLogo: Как реализовать `карту предложений` (иначе`flatMap`)?
NetLogo имеет map
примитив, который запускает задачу репортера для каждого элемента входного списка и собирает список результатов.
Многие языки программирования, которые имеют map
также есть то, что называется flatMap
(или монадический bind
или же collect
или же SelectMany
или же mapcan
или же append-map
), которая делает то же самое, но позволяет (или требует) задаче репортера вместо этого сообщать список результатов. Конечный результат представляет собой один список, содержащий все списки результатов, объединенные.
В логотипе (в том числе в NetLogo) конкатенационная часть называется sentence
поэтому хорошее имя для операции, объединяющей отображение с конкатенацией, может быть sentence-map
,
Так, например, мы хотим:
observer> show sentence-map task [list ? ?] [1 2 3]
observer: [1 1 2 2 3 3]
Обратите внимание, что sentence
не требует, чтобы все его входы были списками. Например, (sentence 1 [2 3] 4)
оценивает [1 2 3 4]
, Итак, наше определение sentence-map
последую примеру. Пример:
observer> show sentence-map task [ifelse-value (? mod 2 = 0) [(list ? ?)] [?]] [1 2 3]
observer: [1 2 2 3]
Как может sentence-map
быть реализованным, и является ли реализация эффективной?
1 ответ
Самый простой способ определить sentence-map
как следует:
to-report sentence-map [f xs]
report reduce sentence map f xs
end
Что касается эффективности, если вы используете NetLogo 5.0.5 или новее, это определение должно работать хорошо (O(n)-ish-runtime).
В NetLogo 5.0.4 и более ранних версиях повторное использование sentence
составит общее время O (n2) из-за этой ошибки NetLogo (где основной причиной была эта ошибка Scala).
Если по какой-то причине вы застряли, используя старую версию NetLogo, вы можете обойти ее, написав свою собственную версию sentence
что делает объединение путем многократного вызова lput
, а затем использовать это внутри sentence-map
,