Skip to content

Instantly share code, notes, and snippets.

@artdent
Created January 16, 2012 21:17
Show Gist options
  • Save artdent/1623095 to your computer and use it in GitHub Desktop.
Save artdent/1623095 to your computer and use it in GitHub Desktop.
Ways by node
(defn collect-ways-by-node [ways]
(loop [ways ways
accum {}]
(if (seq ways)
(let [{:keys [nodes id]} (first ways)
new-accum (zipmap nodes (map vector (repeat id)))]
(recur (rest ways) (merge-with (comp vec concat) accum new-accum)))
accum)))
import collections
def ways_by_node(ways):
ret = collections.defaultdict(list)
for way in ways:
way_id = way['id']
for node_id in way['nodes']:
ret[node_id].append(way_id)
return ret
@artdent
Copy link
Author

artdent commented Jan 16, 2012

Original post: https://plus.google.com/105985814958698329518/posts/CowT87M61WC

Problem description: a Way is an object with an id and a list of node ids, like so (in json): {'id': 'foo', 'nodes': [10, 11]}. Given a list of ways, return a mapping of node ids to a list of way ids that contain each node. Given a list of the way described previously, the return would be {10: ['foo'], 11: ['foo']}

Speculations over why the Clojure solution looks worse than the Python solution:

  • I wrote terrible Clojure and someone with more than a month of experience can improve my code.
  • The Clojure solution is fine and just looks worse because I'm less familiar with the language
  • Immutable data structures are just clumsier to work with despite their other benefits.
  • defaultdict is just super-handy and the clojure code would be easier if defaultdict existed in clojure.core. (It didn't show up in the Python stdlib until version 2.5.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment