clojure filter nested map to return keys based on inner map values

大憨熊 提交于 2019-12-24 01:25:45

问题


For this nested map called "tables",

  (def tables 
   {:tableA {:occupied false :party nil} 
    :tableB {:occupied true :party nil}
    :tableC {:occupied false :party nil}})

how do I filter and get back the keys where :occupied = false ?

correct result should be (:tableA :tableC)

can I do this with "filter" HOF? Should I be using a list comprehension?


回答1:


You could do it pretty easily with keep:

(keep (fn [[k v]] (if-not (:occupied v) k)) tables)

However, as you observed, using for is often a good solution whenever you're mapping / filtering sequences, especially if you're dealing with nested sequences.

(for [[k v] tables :when (not (:occupied v))] k)

I usually prefer using for, especially when I want to use destructuring on the target items. In this case, destructuring is nice for binding the key/value pair with [k v].




回答2:


I'm not sure what your use case is, but can I suggest structuring your data as a set of maps? Sets have certain properties that allow you to query them using relational algebra similar to the way you query tables in SQL. The clojure.set/select function is similar to a WHERE in SQL.

(use 'clojure.set)

(def tables
    #{{:table "A" :occupied false :party nil} 
      {:table "B" :occupied true :party nil}
      {:table "C" :occupied false :party nil}})

(select #(= false (:occupied %)) tables)

Hope this helps!



来源:https://stackoverflow.com/questions/19886035/clojure-filter-nested-map-to-return-keys-based-on-inner-map-values

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!