如何在 clojure 中迭代和合并函数结果?
How to iterate and merge a function results in clojure?
不确定如何表达这个问题,但是,我只是在玩推特 api 和 clojure 作为我想学习 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))
这些只是模型,但是,您明白了。现在,推特 returns 是这样的:[{: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
属性来自所有 collection。
做(get response :text)
或(get-in response [:text])
returnsnil
(假设response
是collection)
那么,如何从 collection 中获取所有 :text
?我接近这个权利吗?我尝试了 (doseq [f followers] (get-tweets f))
和 for
,但它们似乎非常不自然,因为只获取所有推文。
理想的 clojure 方法是什么?
您的 get-tweets
fn 正在返回一系列多个地图,作为向量。然后,您将该功能映射到您的追随者,生成一系列映射序列。这就是为什么有两个括号 - 外部序列对应于关注者列表,每个内部序列是来自一个关注者的所有推文组合在一起。
如果您愿意放弃作者的身份,我认为最简单的方法是使用 flatten
,一个用于解开嵌套顺序数据结构以仅获取项目的函数。这将为您提供一系列没有任何分组的地图。然后,您可以将 :text
映射到它们上面以仅获取文本。
例如
(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
-then-concat
。当您拥有
时,这是首选方法
- 具有某种内部结构的一系列数据项。
- 您想要 "unpack" 以便每个都能生产出您真正想要的一个或多个项目。
它通过将给定函数映射到外部项来生成一堆序列,然后将所有这些序列连接成一个来实现这一点。但在这种情况下,我们的 "unpacking function" 本身就是 map
所以我认为这种方法在这里不一定更清楚。这只是让记住不同级别有点困难:
(mapcat (partial map :text) (get-all-followers-tweets))
不确定如何表达这个问题,但是,我只是在玩推特 api 和 clojure 作为我想学习 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))
这些只是模型,但是,您明白了。现在,推特 returns 是这样的:[{: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
属性来自所有 collection。
做(get response :text)
或(get-in response [:text])
returnsnil
(假设response
是collection)
那么,如何从 collection 中获取所有 :text
?我接近这个权利吗?我尝试了 (doseq [f followers] (get-tweets f))
和 for
,但它们似乎非常不自然,因为只获取所有推文。
理想的 clojure 方法是什么?
您的 get-tweets
fn 正在返回一系列多个地图,作为向量。然后,您将该功能映射到您的追随者,生成一系列映射序列。这就是为什么有两个括号 - 外部序列对应于关注者列表,每个内部序列是来自一个关注者的所有推文组合在一起。
如果您愿意放弃作者的身份,我认为最简单的方法是使用 flatten
,一个用于解开嵌套顺序数据结构以仅获取项目的函数。这将为您提供一系列没有任何分组的地图。然后,您可以将 :text
映射到它们上面以仅获取文本。
例如
(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
-then-concat
。当您拥有
- 具有某种内部结构的一系列数据项。
- 您想要 "unpack" 以便每个都能生产出您真正想要的一个或多个项目。
它通过将给定函数映射到外部项来生成一堆序列,然后将所有这些序列连接成一个来实现这一点。但在这种情况下,我们的 "unpacking function" 本身就是 map
所以我认为这种方法在这里不一定更清楚。这只是让记住不同级别有点困难:
(mapcat (partial map :text) (get-all-followers-tweets))