在clojure中将一系列向量合并为一个向量

时间:2016-11-09 20:52:37

标签: vector clojure functional-programming

我有一个程序可以搜索亚马逊并返回指定图书的信息。一旦完成所有搜索,我希望能够按SalesRank对书籍进行排序。我遇到的问题是能够将矢量组合成一个大型集合。现在我可以让它们逐个打印,但每次迭代都会覆盖前一个。我是一个函数式编程NOOB,所以任何帮助都表示赞赏。以下是一个片段:

(defn get_title_and_rank_for_one_isbn [isbn]

        (def book_title (get-in (amazon_search isbn)[:items 0 :item-atributes :title]))
        (def sales_rank(get-in (amazon_search isbn)[:items 0 :SalesRank]))
        (def book_isbn(get-in (amazon_search isbn)[:items 0 :asin]))

)

(defn get_title_and_rank_for_all_isbns [list_of_isbns]
    (doseq [isbn list_of_isbns] 
        (Thread/sleep 3000)
        (get_title_and_rank_for_one_isbn isbn)
        (def combine_attributes(reduce into [[book_title] [book_isbn] [sales_rank]]))
        (println combine_attributes)
    )

)

2 个答案:

答案 0 :(得分:0)

<!DOCTYPE html>
<html>

<head>
</head>

<body>
<a href="javascript:void(0)" 
  data-href="placehold.it/1x1" 
  title="placehold.it">placehold.it</a>
<script>
  document.querySelector("a").onclick = function(e) {
    e.preventDefault();
    var request = fetch(location.protocol + "//" + this.dataset.href);
    request.then(response => response.blob())
    .then(blob => console.log(blob))
  }
</script>
</body>

</html>

可能有几种方法可以做到这一点,但这只需要一些简化的代码。您可以像这样调用函数:(defn- get-books [data] (letfn [(one-book [book] (let [title (get-in book :title) rank (get-in book :rank) isbn (get-in book :isbn)] {:title title :rank rank :isbn isbn}))] (map one-book data)))) 其中(println (get-books data))是您的json结构。

那么data发生了什么? get-books允许您定义可以在此处封装的函数。 Clojure函数将返回最后定义的东西,在这种情况下,它是leftn函数。事实上,它几乎是唯一“运行”的东西。它通过map函数映射您的数据,该函数使用one-book创建在每本书通过函数时重新绑定的绑定。这取代了您使用let

的想法

同样,def返回其最后一个定义,即键值结构。您可以映射所有数据,然后将其打印出来,将其传递给另一个函数,或者您需要执行的任何操作。

这不是一个确切的解决方案,而是建议如何考虑处理数据以及如何从函数返回值。

答案 1 :(得分:0)

首先观察(amazon_search isbn)每个isbn只运行一次。

然后map独立地搜索每个搜索结果,并将所需数据提取到最终按销售排名排序的新地图中。

 (defn get-book [isbn]
   (let [itm (get-in (amazon_search isbn) [:items 0])]
     {:book/title (get-in itm [:item-attributes :title])
      :book/sales-rank (:SalesRank itm)
      :book/isbn (:asim itm)}))

 (defn get-books-sorted-by-sales-rank [isbns]
    (->> isbns (map get-book) (sort-by :book/sales-rank)))

 ;; a bit more performant