如何从Clojure中的嵌套映射生成列表?
我有一个原子:如何从Clojure中的嵌套映射生成列表?,clojure,maps,Clojure,Maps,我有一个原子: (def test (atom {:james {:friends [:lucy :john :daisy]}, :lucy {:friends [:james :daisy]}, :daisy {:friends [:james :lucy]}, :john {:friends [:james]}})) Giving:james作为一个参数,我需要迭代它的:friends,并
(def test (atom {:james {:friends [:lucy :john :daisy]},
:lucy {:friends [:james :daisy]},
:daisy {:friends [:james :lucy]},
:john {:friends [:james]}}))
Giving:james作为一个参数,我需要迭代它的:friends,并将:james friends的每个friends放入一个列表中。结果一定是这样的:
(:james :daisy :james :james :lucy)
这是我迄今为止最大的努力:
(def user :james)
(def test2 (atom []))
(defn access
[user]
(get-in @test [user :friends]))
(doseq [connection (access user)]
(swap! test2 concat (access connection)))
@test2
我不认为使用另一个atom test2是最惯用的方法。没错,您不需要中间的atom
(def users (atom {:james {:friends [:lucy :john :daisy]},
:lucy {:friends [:james :daisy]},
:daisy {:friends [:james :lucy]},
:john {:friends [:james]}}))
(defn friends [dict level users]
(-> (fn [users] (mapcat #(get-in dict [% :friends]) users))
(iterate users)
(nth level)))
(friends @users 2 [:james])
没错,你不需要中间原子
(def users (atom {:james {:friends [:lucy :john :daisy]},
:lucy {:friends [:james :daisy]},
:daisy {:friends [:james :lucy]},
:john {:friends [:james]}}))
(defn friends [dict level users]
(-> (fn [users] (mapcat #(get-in dict [% :friends]) users))
(iterate users)
(nth level)))
(friends @users 2 [:james])
我只会在整个应用程序的最外层使用原子。它们是可共享的、可并发访问的、可变的。。。数据通常是全球性的 写下你需要的函数,让它们尽可能好地与这些事情无关。如果您最终使用纯函数,那么测试就容易多了。如果你想积累数据,那就塑造它;返回前有辅助计算步骤等 这大概就是我要走的路线。注意,有很多方法可以剥猫的皮来浓缩你的列表,我选择了mapcat: defn用户 [用户名称] 获取用户的用户名 德芬朋友 [用户] 获取用户:好友 defn用户朋友 [用户名称] 一些->>用户名用户朋友 德芬朋友 [用户名称] 当让[好友名称用户好友用户用户名] mapcat部分用户好友用户好友名称;XXX累积混凝土的更换 最后,在您的测试或REPL中: 让[用户{:詹姆斯{:朋友[:露西:约翰:黛西]} :露西{:朋友[:詹姆斯:黛西]} :黛西{:朋友[:詹姆斯:露西]} :约翰{:朋友[:詹姆斯]}] 好友用户:詹姆斯 ; => :詹姆斯:黛西:詹姆斯:詹姆斯:露西
我只会在整个应用程序的最外层使用原子。它们是可共享的、可并发访问的、可变的。。。数据通常是全球性的 写下你需要的函数,让它们尽可能好地与这些事情无关。如果您最终使用纯函数,那么测试就容易多了。如果你想积累数据,那就塑造它;返回前有辅助计算步骤等 这大概就是我要走的路线。注意,有很多方法可以剥猫的皮来浓缩你的列表,我选择了mapcat: defn用户 [用户名称] 获取用户的用户名 德芬朋友 [用户] 获取用户:好友 defn用户朋友 [用户名称] 一些->>用户名用户朋友 德芬朋友 [用户名称] 当让[好友名称用户好友用户用户名] mapcat部分用户好友用户好友名称;XXX累积混凝土的更换 最后,在您的测试或REPL中: 让[用户{:詹姆斯{:朋友[:露西:约翰:黛西]} :露西{:朋友[:詹姆斯:黛西]} :黛西{:朋友[:詹姆斯:露西]} :约翰{:朋友[:詹姆斯]}] 好友用户:詹姆斯 ; => :詹姆斯:黛西:詹姆斯:詹姆斯:露西
进行此类查询的另一种方法或称之为“间接”方法是通过,首先将嵌套映射转换为事实: def友谊地图猫fn[[p{xs:friends}] 对于[f xs] [p:个人/朋友f] {:james{:friends[:lucy:john:daisy]}, :露西{:朋友[:詹姆斯:黛西]}, :黛西{:friends[:james:lucy]}, :约翰{:朋友[:詹姆斯]} ;; => [:詹姆斯:人/朋友:露西] [:詹姆斯:人/朋友:约翰] [:詹姆斯:人/朋友:黛西] [:露西:人/朋友:詹姆斯] [:露西:人/朋友:黛西] [:黛西:人/朋友:詹姆斯] [:黛西:人/朋友:露西] [:约翰:人/朋友:詹姆斯] 然后使用自定义规则(如friend和friend of friend)对事实执行数据日志查询。例如,寻找朋友的朋友:詹姆斯: d/q'[:查找[?f…] :朋友的朋友在哪里 :单位:美元?p%] 友谊 :詹姆斯 “[[friend?p?f [?p:个人/朋友?f]] [朋友的朋友?p?f 朋友?p?x 朋友?x?f [not=?p?f]] ;; => [:黛西:露西] 在哪里 [:查找[?f…] :朋友的朋友在哪里 :单位:美元?p%] 是查询,友谊是事实并映射到$,:james是映射到参数的查询主题?p和%是定义为以下内容的规则: 什么是朋友? [?p:person/friend?f]];?p有一个属性:person/friend用?f定义 [朋友的朋友?p?f;2.朋友的朋友 朋友?p?x;?p和?x是基于1的朋友 朋友?x?f;?x和?f是朋友 [not=?p?f]]?p和?f不是同一个人
注意:上面的示例使用的是另一种方式,或者您称之为“间接”方式来执行此类查询,即首先将嵌套映射转换为事实: def友谊地图猫fn[[p{xs:friends}] 对于[f xs] [p:个人/朋友f] {:james{:friends[:lucy:john:daisy]}, :露西{:朋友[:詹姆斯:黛西]}, :黛西{:friends[:james:lucy]}, :约翰{:朋友[:詹姆斯]} ;; => [:詹姆斯:人/朋友:露西] [:詹姆斯:人/朋友:约翰] [:詹姆斯:人/朋友:黛西] [:露西:人/朋友:詹姆斯] [:露西:人/朋友:黛西] [:黛西:人/朋友:詹姆斯] [:黛西:人/朋友:露西] [:约翰:人/朋友:詹姆斯] 然后使用自定义规则(如friend和friend of friend)对事实执行数据日志查询。例如,寻找朋友的朋友:詹姆斯: d/q'[:查找[?f…] :朋友的朋友在哪里 :单位:美元?p%] 友谊 :詹姆斯 “[[friend?p?f [?p:个人/朋友?f]] [朋友的朋友?p?f 朋友?p?x 朋友?x?f [not=?p?f]] ;; => [:黛西:露西] 在哪里 [:查找[?f…] :朋友的朋友在哪里 :单位:美元?p%] 是查询,友谊是事实并映射到$,:james是映射到参数的查询主题?p和%是定义为以下内容的规则: 什么是朋友? [?p:person/friend?f]];?p有一个属性:person/friend用?f定义 [朋友的朋友?p?f;2.朋友的朋友 朋友?p?x;?p和?x是基于1的朋友 朋友?x?f;?x和?f是朋友 [not=?p?f]]?p和?f不是同一个人
注意:上面的示例使用的是,这里有一种方法可以解决使用core.logic和facts的可传递好友问题。首先,为友谊做一个事实DB和DB rel:
(require '[clojure.core.logic :refer :all]
'[clojure.core.logic.pldb :as pldb])
(def input
{:james {:friends [:lucy :john :daisy]},
:lucy {:friends [:james :daisy]},
:daisy {:friends [:james :lucy]},
:john {:friends [:james]}})
(pldb/db-rel friend p1 p2)
(def friends
(apply pldb/db
(for [[p1 {:keys [friends]}] input
p2 friends]
[friend p1 p2])))
然后编写一个函数,将一个朋友的答案绑定到该朋友的所有朋友的朋友
下面是一个用core.logic和facts解决可传递朋友问题的方法。首先,为友谊做一个事实DB和DB rel:
(require '[clojure.core.logic :refer :all]
'[clojure.core.logic.pldb :as pldb])
(def input
{:james {:friends [:lucy :john :daisy]},
:lucy {:friends [:james :daisy]},
:daisy {:friends [:james :lucy]},
:john {:friends [:james]}})
(pldb/db-rel friend p1 p2)
(def friends
(apply pldb/db
(for [[p1 {:keys [friends]}] input
p2 friends]
[friend p1 p2])))
然后编写一个函数,将一个朋友的答案绑定到该朋友的所有朋友的朋友
非常感谢你!如果我想数一数这些朋友并进行分类,把这个列表变成这样:{:詹姆斯3,:黛西1,:露西1},你知道我该怎么做吗?非常感谢!如果我想数一数这些朋友并进行分类,把这个列表变成这样:{:詹姆斯3,:黛西1,:露西1},你知道我该怎么做吗?非常感谢!如果我想数一数朋友并进行排序,把列表变成这样:{:詹姆斯3,:黛西1,:露西1},你知道我该怎么做吗?频率朋友用户:詹姆斯->{:黛西1,:詹姆斯3,:露西1}哦,很简单!我怎样才能按val分类呢?我找到了这个,但是还有更好的方法吗?非常感谢!如果我想数一数朋友并进行排序,把列表变成这样:{:詹姆斯3,:黛西1,:露西1},你知道我该怎么做吗?频率朋友用户:詹姆斯->{:黛西1,:詹姆斯3,:露西1}哦,很简单!我怎样才能按val分类呢?我找到了这个,但是还有更好的方法吗?