Filtering out illegal moves from a map of available moves I'm writing a console blackjack game.

To hold all the possible moves a player can make, I have a map that maps a keyboard key to a move keyword:

(def move-map {\s :stand
               \h :hit
               \p :split
               \d :double})


Splitting and doubling are only available options during the first move though, so I'd like to filter them out of the available moves before verifying the user's input if they aren't legal moves.

My current method is to indicate which are legal using a flag for doubling and one for splitting, then filtering the map if a flag isn't set:

(defn- filter-moves [moves can-split? can-double?]
  (let [r-split (if can-split? moves (filter #(not= :split (second %)) moves))
        r-doub (if can-double? r-split (filter #(not= :double (second %)) r-split))]
    (into {} r-doub)))


The problem is, this contains a fair amount of redundancy. It should only iterate the map once because filter is lazy, but I'm still not happy with this solution.

Usage:

(filter-moves move-map true false)

=&gt; {"s" :stand, "h" :hit, "p" :split}


Any improvement suggestions would be appreciated. I'm not against redesigning the function if it helps readability and maintainability.
You can iterate once by using remove in combination with a set of illegal moves:

(defn- filter-moves [moves can-split? can-double?]
  (let [illegal? (cond-&gt; #{} 
                   (not can-split?) (conj :split)
                   (not can-double?) (conj :double))]
    (into {} (remove #(illegal? (second %)) moves))))


What's more, If I understand correctly that moves is the map mapping keys to moves. In my opinion, this map has no place in your core game logic: have your filter-moves function manipulate only sets of moves and keep any notion of user input at the edge of your system.