我是一個clojure的完全新手,所以請原諒下面的愚蠢......但我試圖在空間上分割一個字符串矢量,然後從單個序列中獲取所有結果向量矢量中的所有唯一字符串(其中我對序列類型沒有挑剔)。這是我嘗試的代碼。使用clojure來獲取字符串向量中的獨特單詞集合的慣用方式
(require '[clojure.string :as str])
(require '[clojure.set :as set])
(def documents ["this is a cat" "this is a dog" "woof and a meow"])
(apply set/union (map #(str/split % #" ") documents))
我本來期望這回一組唯一字,即
#{"woof" "and" "a" "meow" "this" "is" "cat" "dog"}
,而是它返回的非唯一字的載體,即
["woof" "and" "a" "meow" "this" "is" "a" "cat" "this" "is" "a" "dog"]
最後,我只是在一個電話中包裝,即
(set (apply set/union (map #(str/split % #" ") documents)))
,並得到了我想要的東西:
#{"dog" "this" "is" "a" "woof" "and" "meow" "cat"}
,但我不明白爲什麼這應該是這樣的。根據docs聯合函數返回一個集合。那麼爲什麼我會得到一個向量?
第二個問題,另一種方法就是
(distinct (apply concat (map #(str/split % #" ") documents)))
也返回我想要的東西,雖然以列表的形式,而不是設置形式。但是一些討論on this prior SO表明concat非常慢,可能比set操作(?)慢。
這是正確的...是否有任何其他理由更喜歡另一種方法(或某種第三種方法)?
我真的不在乎我是否得到一個向量或一組來自另一端的集合,但最終會關心性能方面的考慮。我試圖通過實際生成對我的文本挖掘習慣有用的東西來學習Clojure,因此最終這部分代碼將成爲工作流程的一部分,以便高效地處理大量文本數據......獲取它的時間現在是正確的,表現明智的,而且一般來說不是愚蠢的。
謝謝!
謝謝。我認爲聯合函數會返回一個集合,不管它通過了什麼......不要猜測! –
@PaulGowder這可能有助於考慮具有契約的聯合函數 - 契約的程序員一方將集合傳遞給union,而契約的函數一方則返回一個集合。傳遞媒介而不是集合打破了合同,所以工會可能會或可能不會完成交易的結束。如果它報告了有關其輸入的錯誤可能不那麼令人不安,但隨着時間的推移,您可能會認爲這不是一個問題。 –
@PaulGowder如果你看看源代碼,你會發現'clojure。set/union''將較小集合的元素連接到較大的集合中。因此,例如,'(clojure.set/union(set(range 10))(range 3))'工作,但'(clojure.set/union(set(range 3))n(range 10))''' *序列*'(2 1 0 0 1 2 3 4 5 6 7 8 9)'。正如@Brian所暗示的那樣,你必須將這種行爲視爲實施事故,這種事故在未來可能會發生變化。 – Thumbnail