2011-10-29 108 views
2

我有以下工作代碼嵌套地圖(實際上鳴叫數據)的列表轉換成地圖:替代轉換嵌套的地圖列表,地圖

(defn filter 
    "This function returns a map with the user as key, #followers as value" 
    [raw-tweets] 

    (let [users (map :user raw-tweets) 
     names (map :name users) 
     followers (map :followers_count users)] 
    (zipmap names followers))) 

雖然這正常工作,我想知道在Clojure中是否會有更習慣的方式來做到這一點。任何替代品?

回答

2

你有什麼是好的,但因爲你去通過降低你可以建立地圖:

 
(defn user-followers [raw-tweets] 
    (reduce #(assoc %1 (:name %2) (:followers_count %2)) 
    {} (map :user raw-tweets))) 
+0

不錯,乾淨。謝謝 –

1

我只是開始學習clojure,但我認爲這種方式可能會更習慣。無論如何,這是一種選擇。

(defn filter 
    "This function returns a map with the user as key, #followers as value" 
    [raw-tweets] 
    (into {} (map #(let [user (:user %)] 
        [(:name user) (:followers_count user)]) 
       raw-tweets))) 

它映射了與檢索每個鳴叫用戶,並返回一個矢量的名稱和追隨者計算該用戶的功能的原始鳴叫。 into函數接受兩個序列,並將第二個元素的每個元素連接到第一個元素上,這會在從濾波函數返回之前將矢量列表轉換爲映射。

1

我發現@達安的回答很好,但我會添加解構到混合中。

(defn filter-tweets 
    "This function returns a map with the user as key, #followers as value" 
    [raw-tweets] 
    (into {} (map (fn [{{name :name follower-count :followers_count} :user}] 
        [name follower-count]) 
       raw-tweets))) 
1

我不喜歡(map (fn ...))模式 - 它真的只是寫一個醜陋的方式一個for理解。我寫這篇文章的:

(into {} 
     (for [{:keys [user]} raw-tweets] 
     ((juxt :name :followers_count) user))) 

還是這個,感覺有點不太自然的我,但避免了發明了你只是還是要用一次值的名稱。

(into {} (map (comp (juxt :name :followers_count) :user) 
       raw-tweets))