我有以下工作代码将带有嵌套地图的列表(实际上是推文数据)转换为地图:
(defn filter
"This function returns a map with the user as key, #followers as value"
[raw-tweets]
(let [users (map :user raw-tweets)
names (map :name users)
followers (map :followers_count users)]
(zipmap names followers)))
虽然这可以按预期工作,但我想知道在Clojure中是否会有更惯用的方法。任何替代方案?
答案 0 :(得分:2)
你所拥有的很好,尽管你可以使用reduce:
来构建地图(defn user-followers [raw-tweets] (reduce #(assoc %1 (:name %2) (:followers_count %2)) {} (map :user raw-tweets)))
答案 1 :(得分:1)
我只是开始学习clojure,但我认为这种方式可能更具惯用性。无论如何,它都是另一种选择。
(defn filter
"This function returns a map with the user as key, #followers as value"
[raw-tweets]
(into {} (map #(let [user (:user %)]
[(:name user) (:followers_count user)])
raw-tweets)))
它使用一个函数映射原始推文,该函数检索每条推文的用户,并返回一个带有该用户名称和关注者计数的向量。 into函数接受两个序列并将第二个元素的每个元素连接到第一个元素上,这将在向量函数返回之前将向量列表转换为映射。
答案 2 :(得分:1)
我发现@ Daan的答案很好,但我会在混音中添加解构。
(defn filter-tweets
"This function returns a map with the user as key, #followers as value"
[raw-tweets]
(into {} (map (fn [{{name :name follower-count :followers_count} :user}]
[name follower-count])
raw-tweets)))
答案 3 :(得分:1)
我不喜欢(map (fn ...))
模式 - 这只是一种写出for
理解的丑陋方式。我把它写成:
(into {}
(for [{:keys [user]} raw-tweets]
((juxt :name :followers_count) user)))
或者这个,对我来说感觉不那么自然,但是避免为你刚才要使用的价值创造名字。
(into {} (map (comp (juxt :name :followers_count) :user)
raw-tweets))