title: In Clojure how can I merge two vectors of maps?
body: <p>I have a vector of entities (maps), I have filtered this vector to those entities with a particular key. Then I apply a function to update some values in those entities, and now have a subset that I'd like to merge with the original superset.</p>
  
  <pre><code>world     [{a} {b} {c} {d} {e}]
  a         [{b} {d} {e}]            ; (filter matches? world)
  b         [{b'} {d'} {e'}]         ; (map func a)
  new-world [{a} {b'} {c} {d'} {e'}] ; (merge world b)
  </code></pre>
  
  <p>How can I merge my update <code>b</code> with the original <code>world</code>?</p>
  
  <p>My map structure is:</p>
  
  <pre><code>{:id identity
   :attrs {:property1 {:param1 value
                       :param2 value}
           :property2 {}}
  </code></pre>
  
  <p>There can be a variable number of properties. Properties can have 0 (<code>{}</code>) or more params. The only part of the map that is changing are the values, and only some of them.</p>
  
  <p>I have to peer into each map to identify it, and then merge accordingly? What is an idiomatic way to do this?</p>
  
  <p>Clojure's <a href="http://clojuredocs.org/clojure_core/clojure.core/map" rel="nofollow noreferrer">map function</a> can take multiple sequences, but won't compare my subset <code>b</code> to the whole superset <code>world</code>, only <code>b</code> number of world entities, and stop once <code>b</code> is exhausted.</p>
  
  <pre><code>&gt; (map #(str %1 " " %2) [1 2 3 4 5] [6 7 8])
  ("1 6" "2 7" "3 8")
  </code></pre>
  
  <p>Have I chosen the wrong structure for my data in the first place? Would I be better off without a vector and just one map?</p>
  
  <pre><code>{:entid1
     {:property1 {:param1 value :param2 value}
      :property2 {}}
   :entid2
     {:property1 {:param1 value :param2 value}
      :property2 {:param1 value}
      :property3 {:param1 value :param2 value :param3 value}}}
  </code></pre>
  
  <p><a href="https://stackoverflow.com/questions/10209218/clojure-merging-two-array-of-maps">This question</a> looks similar but does not merge my vectors correctly.</p>
  
  <hr>
  
  <p><strong>Real world implementation</strong></p>
  
  <p>My actual code is <a href="https://github.com/gknapp/jump" rel="nofollow noreferrer">part of a game I'm writing</a> to familiarise myself with Clojure (ClojureScript in this instance).</p>
  
  <p>The game state (world) is as follows:</p>
  
  <pre><code>[{:id :player,
    :attrs
      {:gravity {:weight 10},
       :jump {:height 60, :falling false, :ground true},
       :renderable {:width 37, :height 35},
       :position {:x 60, :y 565},
       :walk {:step 4, :facing :right},
       :input {},
       :solid {:blocked false}}}
   {:id wall1,
    :attrs
      {:solid {},
       :position {:x 0, :y 0},
       :renderable {:width 20, :height 600}}}
   {:id wall2,
    :attrs
      {:solid {},
       :position {:x 780, :y 0},
       :renderable {:width 20, :height 600}}}
   {:id platform3,
    :attrs
      {:solid {},
       :position {:x 20, :y 430},
       :renderable {:width 600, :height 20}}}] 
  </code></pre>
  
  <p>I update the world on each animation frame, then re-render the canvas.</p>
  
  <pre><code>(defn game-loop []
    (ui/request-frame game-loop)
    (-&gt; world
        system/update!
        ui/render))
  </code></pre>
  
  <p><code>system/update!</code> is:</p>
  
  <pre><code>(defn update! [world]
    (let [new-world (-&gt;&gt; @world
                        (phys/move @player/input-cmd))]
      (player/clear-cmd)
      (reset! world new-world)
      @world))
  </code></pre>
  
  <p>My plan was to have a chain of systems updating the world in the thread last macro. I am in the process of writing <code>phys/move</code>.</p>
  
  <p>This means that systems have to update the world, instead of just returning their effect on the world (vector of changes).</p>
  
  <p>I'm contemplating if it's more manageable to have the <code>system/update!</code> function manage the effects on the world (applying the updates). So systems only return their list of changes. Something like:</p>
  
  <pre><code>(defn update! [world]
    (let [updates []
          game @world]
       (conj updates (phys/move @player/input-cmd game))
       (conj updates (camera/track :player game))
       ; etc.
       (reset! world
         (map #(update-world updates %) world))
       @world))
  </code></pre>
  
  <p>Repeated <code>(conj updates (func world))</code> feels clunky though. This is possibly more work than just merging updates (or returning an modified entity) in a system function.</p>
  
  <p>How to elegantly pass state changes between my system functions (<code>phys/move</code>, <code>camera/track</code>), and subsystem functions (<code>walk</code>, <code>jump</code>)?</p>
  
  <p>My stab at applying Joaquin's map only approach to my <code>move</code> system:</p>
  
  <pre><code>(ns game.phys)
  
  (def step 4)
  (def height 50)
  
  (defn walk?
    "is this a walk command?"
    [cmd]
    (#{:left :right} cmd))
  
  (defn walks?
    "update? equivalent"
    [entity]
    (contains? (:attrs entity) :position))
  
  (defn walk
    [cmd entity]
    (if (walks? entity)
      (let [x (get-in entity [:attrs :position :x]
            op (if (= cmd :left) - +)
            update {:attrs {:position {:x (op x step)}
                            :walk     {:facing cmd}}}]
        (merge entity update))
      entity))
  
  ; cmd is a deref'ed atom that holds player input commands
  ; e.g. :left :right: :jump
  (defn move
    [cmd world]
    (cond
      (walk? cmd) (map #(walk input-cmd %) world)
      (jump? cmd) (map #(jump height %) world)
      :else world))
  </code></pre>