如何迭代和合并函数导致clojure?

时间:2015-03-15 16:03:11

标签: clojure

不确定如何表达这个问题,但是,我只是在玩twitter api和clojure作为我想学习clojure的一部分。

我不确定克服这个问题的方法是什么

我试图获得所有关注者的前5条推文。我可以使用api获取关注者列表,并且我有一个关注者列表screen_name。现在,我有一个函数来从用户那里获取最新的5条推文。在C#中,我只是声明一个List<object>并在for循环中添加推文。 Clojure并没有那么好的工作......所以这就是我想要做的事情:

(defn get-tweets
  [follower]
  {:text (str "I am " follower)
   :favs 0})

(defn get-all-followers-tweets
  []
  (let [followers ["a" "b" "c"]
        followers-tweets (map #(get-tweets %) followers)]
    followers-tweets))

这些只是模型,但是,你明白了。现在,Twitter返回类似这样的内容:[{:text "ssd" :fav 1} {:text "fed" :fav 2}]

所以当我致电get-all-followers-tweets时,我明白了:

(({:text "I am a", :favs 0} {:text "I am b", :favs 0} {:text "I am c", :favs 0}))

我不知道为什么数据在2个括号中,我猜测它与map有关但是,我只需要所有:text属性集合。

执行(get response :text)(get-in response [:text])会返回nil(假设response是集合)

那么,如何从集合中获取所有:text?我接近这个吗?我尝试了(doseq [f followers] (get-tweets f))for,但是对于获取所有推文看起来非常不自然。

这种理想的clojure方式是什么?

1 个答案:

答案 0 :(得分:1)

您的get-tweets fn正在返回一系列多个地图,作为向量。然后,您将该函数映射到关注者,生成一系列映射序列。这就是为什么有两个括号 - 外部序列对应于关注者列表,每个内部序列都是来自一个跟随者组合在一起的所有推文。

我认为最简单的方法是,如果你没有丢弃作者的身份,那就是使用flatten,这是一个用于解开嵌套顺序数据结构的函数来获取项目。这将为您提供一系列没有任何分组的地图。然后,您可以将:text映射到它们上面以获取文本。

e.g。

(defn get-all-followers-tweets
  []
  (let [followers ["a" "b" "c"]
        followers-tweets (map get-tweets followers)]
    (flatten followers-tweets)))

(map :text (get-all-followers-tweets))

也许更通用的解决方案是考虑mapcat,代表map - 然后 - concat

时,这是首选方法
  • 一系列具有某种内部结构的数据项。
  • 您要“解包”,以便每个人都能生成一个或多个您真正想要的物品。

它通过将给定函数映射到外部项来生成一堆序列,然后将所有这些序列连接成一个来完成此操作。但在这种情况下,我们的“解包功能”本身就是map所以我不认为这种方法在这里必须更加清晰。这使得记住不同级别变得有点困难:

(mapcat (partial map :text) (get-all-followers-tweets))