title: Run a 3-arg (etc) function against a sequence of inputs
body: <p>I'm trying to write some clojure which builds up a data-structure that will be valid clojure code as well. (note I'm not building a macro here: just a function that happens to return clojure code).</p>
  
  <p>Here's my working bit:</p>
  
  <pre><code>(defn create-clause [  property operator value  ]
    (list (symbol operator) (symbol property) (symbol value))
  )
  
  (create-clause "b" "&lt;" "5")
  </code></pre>
  
  <p>So this creates a 'clause' like this:</p>
  
  <pre><code>(&lt; b 5)
  </code></pre>
  
  <p>And this works.</p>
  
  <p>What I want to do is end up with something like this:</p>
  
  <pre><code>(and (= AccountType "current") (&lt; Balance 0))
  </code></pre>
  
  <p>I can chain up a couple of clauses manually like this:</p>
  
  <pre><code>(list 'and (create-clause "a" "=" "current") (create-clause "b" "&lt;" "0"))
  </code></pre>
  
  <p>Which results in:</p>
  
  <pre><code>(and (= a "current") (&lt; b 0))
  </code></pre>
  
  <p>But I want a function that takes my 3-string arguments  "property" "operator" "value" , creates the clause and results in a combined 'and' list of all the clauses which can be evaluated (assume the symbols are bound in a 'let' of course...)</p>
  
  <p>EDIT: Got a bit closer but still no cigar....</p>
  
  <p>Slightly refactored the func - so it now takes a single argument of a list , rather than 3 separate arguments:</p>
  
  <pre><code>(defn create-clause [  [ property operator value ]  ]
    (list (symbol operator) (symbol property) (symbol value))
  )
  
  (create-clause [ "b" "&lt;" "5" ] )
  </code></pre>
  
  <p>Now using a loop/recur - and I can nearly get what I need:</p>
  
  <pre><code>(list 'and (loop [ input [ "a" "&lt;" "10" , "b" "&lt;" "5" ] output [] ]
    (if (= (count input) 0) output
    (recur (drop 3 input) (conj output (create-clause(take 3 input)))))))
  </code></pre>
  
  <p>The result of the above is:</p>
  
  <pre><code>(and [(&lt; a 10) (&lt; b 5)]) ; wrong - don't want that internal vector wrapper...
  </code></pre>
  
  <p>EDIT #2:</p>
  
  <p>So I'm thinking I have accumulate the result somewhere in my loop - so I might was well stick to using the vector as above (but dropping the (list 'and...) ) - but then I should be able to apply something to the result of it which will have the effect of turning this something like this structure:</p>
  
  <pre><code>[ (= 1 1) (= 1 1) ]
  </code></pre>
  
  <p>Into this structure:</p>
  
  <pre><code>(and (= 1 1) (= 1 1))
  </code></pre>
  
  <p>But now I'm stuck again.....</p>
  
  <p>EDIT #3:</p>
  
  <p>Ok , I got there - I have ended up with an unholy mess - but at least it works and I can start refactoring now !</p>
  
  <pre><code>(conj (seq (loop [ input [ "AccountType" "=" "current" , "Balance" "&lt;" 5 ] output [] ]
    (if (= (count input) 0) output
    (recur (drop 3 input) (conj output (create-clause(take 3 input))))))) 'and)
  (and (= AccountType "current") (&lt; Balance 5))
  </code></pre>