不确定如何表达这个问题,但是,我只是在玩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方式是什么?
答案 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))