4

I need to iterate over a specific agentset of patches and get the neighbors of them all and then join those...

I'd do something like

reduce patch-set (map [patch-set neighbors self] patches with [somecondition?]) 

But MAP and REDUCE won't work on agentsets!

caeus
  • 3,084
  • 1
  • 22
  • 36

2 Answers2

5

The normal idea of a map does not really make sense for a set, but you can produce a list with of, and then convert it to a patch set.

let _nbrs patch-set [neighbors] of mypatches

You filter either mypatches or _nbrs with with on any condition you wish.

Alan
  • 9,410
  • 15
  • 20
  • 1
    This is exactly right. In general, `map` and `of` are analogous, as are `filter` and `with`, and `foreach` and `ask`. There isn't really an agentset analog of `reduce`, though. – Bryan Head Jun 27 '16 at 14:02
  • I don't see how Alan or @BryanHead are right about this. Sometimes you want a new list which is the result of applying some function to an agentset. Why on earth can't you have that? How are agentsets different from lists? – Joanna Bryson Aug 02 '16 at 21:43
  • 1
    Joanna, that's pretty much exactly what `of` does. Could you give an example of what you have in mind? As for how agentsets and lists are different: since agentsets only contain agents, you can have the agents themselves run the function, rather than passing in the agents as an argument to the function (there are other differences, but this is the important one here). This is a significant advantage that agentsets have over lists. If you'd like a more detailed answer, feel free to open a new SO question; I don't have enough room here. – Bryan Head Aug 03 '16 at 01:35
  • No, really it's not. See my answer below. – Joanna Bryson Aug 03 '16 at 23:21
  • I think the main problem is people don't expect netlogo to be used to model social agents. I mean, I know you can make little networks and then probably do things across the edges or something (do those list?) but I never ever use graphs to represent societies, I'm antirealist about edges. So my agents often have lists / agentsets of others they want to think about. Map would be perfect. – Joanna Bryson Aug 03 '16 at 23:23
0

Here is a crazy hack I did to handle this kind of problem. Note that what I really wanted to do was to make a list of the numerical values resulting from applying a function to every agent in an agentset, but no. I have to get them to all apply the function about me, then I have to call the function one time extra to find out what the result was that got passed to me. I also had to rewrite the function so that I can have either the agent I'm interested in as the argument (if I'm running it) or me in the argument (if an agent is running it about me). Sheesh!

to-report min-edge-distance [agentset maxsize]
  report ifelse-value (any? agentset)
    [edge-distance min-one-of agentset [edge-distance myself true] false]  ; grr, what I want is min map edge-distance agentset, instead I have to do backflips
    [maxsize]
end


to-report edge-distance [alex me?]
  report ifelse-value (me?)  ;because of netlogo's perverse syntax, I've been forced to ask someone else to figure out my edge distance – alex may be me!
   [(distance alex) * (sqrt [energy] of alex / (sqrt [energy] of alex + sqrt energy) )] ;alex is me!
   [(distance alex) * (sqrt energy / (sqrt [energy] of alex + sqrt energy) )] ; alex is not me
end
  • This code is not a close match to the original question, but in any cas you definitely do not need these gymnastics. The answer I gave to your question is correct. If your objection is that you cannot use `of` with tasks (which is admittedly annoying but well documented), you can always get a list of turtles as `[self] of turtles` and map over that. Separately, although it is entirely distinct from your question, you should turn `edge-distance` into a pure function rather than a turtle reporter. – Alan Aug 04 '16 at 04:18
  • Hi, I didn't claim it was a close match, I claimed it was another case where you want mapping. Thanks for your idea about how to make a list of turtles, but it still seems silly to need to do that. Even if agentsets are more special than lists, why not overload map & reduce? Also, what is the advantage of not assuming that edge-distance is run by a turtle needing to know where it's edge is? – Joanna Bryson Aug 04 '16 at 17:40
  • I would guess it's to keep agentset operations speedy by reducing type checking. (Agentsets only hold a single type.) In any case, `of` substitutes for `map` unless you need a task. If you need a task, you can cast to list and use `map`. E.g., `min map [edge-distance self ?] [self] of turtles`, assuming edge-distance is rewritten to be a pure function with just one line in the body: `report sqrt [energy] of #a1 / (sqrt [energy] of #a2 + sqrt [energy] of #a1)`. (When pure functions are possible, they are imo desirable, but that's somewhat a matter of taste.) – Alan Aug 04 '16 at 17:58