2011-06-06 29 views
1

首先,我是一個Clojure初學者,因爲我的英語不好。構建一個地圖列表

假設你有一個函數返回包含各種信息的地圖列表(在本例中爲Systeminformation)。

我想出了下面的例子,但它看起來錯了,並且過於複雜。

我的問題是'對於[磁盤(文件/ listRoots)'已經返回一個列表,我必須合併2列表才能得到所需的輸出,爲此必須存在一個更好的解決方案。

我希望你們中的某個人能夠啓發我如何以更多的「Clojure方式」來做到這一點。

(import 
[java.lang Runtime System] 
[java.io File]) 

(defn get-sysinfo [] 
(let [basic-info (list 
       {:name "Processor Count:", :value (. (Runtime/getRuntime) availableProcessors)} 
       {:name "OS Name:", :value (System/getProperty "os.name")} 
       {:name "OS Arch:", :value (System/getProperty "os.arch")} 
       {:name "User Name:", :value (System/getProperty "user.name")} 
       {:name "Java Version:", :value (System/getProperty "java.version")})] 
    (concat basic-info (for [disk (File/listRoots)] 
         {:name (str "Disk " (. disk getAbsolutePath)), :value (str "Free Space " (float (/ (. disk getFreeSpace) (* 1024 1024 1024))) " GB")})))) 

在此先感謝

馬庫斯

回答

1

您也可以使用小list*幫手。它從給定的元素創建一個列表。最後一個被作爲尾部列表。所以「合併」隱含地發生。

(defn get-sysinfo 
    [] 
    (list* 
    {:name "Processor Count:" :value (.availableProcessors (Runtime/getRuntime))} 
    {:name "OS Name:", :value (System/getProperty "os.name")} 
    {:name "OS Arch:", :value (System/getProperty "os.arch")} 
    {:name "User Name:", :value (System/getProperty "user.name")} 
    {:name "Java Version:", :value (System/getProperty "java.version")} 
    (for [disk (File/listRoots)] 
     {:name (str "Disk "  (.getAbsolutePath disk)) 
     :value (str "Free Space " (float (/ (.getFreeSpace disk) 
              (* 1024 1024 1024))) 
        " GB")}))) 

但是,也許你真的想返回一張地圖?

(defn get-sysinfo-map 
    [] 
    (into {"Processor Count" (.availableProcessors (Runtime/getRuntime)) 
     "OS Name"   (System/getProperty "os.name") 
     "OS Arch"   (System/getProperty "os.arch") 
     "User Name"  (System/getProperty "user.name") 
     "Java Version" (System/getProperty "java.version")} 
     (for [disk (File/listRoots)] 
      [(str "Disk " (.getAbsolutePath disk)) 
      (float (/ (.getFreeSpace disk) (* 1024 1024 1024)))]))) 
+0

酷,我不知道該列表*幫手,多數民衆贊成正是我一直在尋找適合的get-SYSINFO地圖建議:) – 2011-06-06 12:36:06

+0

+1:我覺得這是組織數據的最自然的方式對於這個問題 – mikera 2011-06-06 16:01:07

1

由於您使用(用於...)來轉換每個元素,地圖似乎是一個更合乎邏輯的選擇。你不能真正避免合併兩個列表,因爲一個是「固定」的,另一個是稍後從文件列表中生成的。

使用(.methodName對象)而不是(。object methodName)也是更習慣 - 儘管這純粹是一個樣式問題。

我會做這樣的:

(defn get-sysinfo [] 
    (concat (list 
      {:name "Processor Count:", :value (. (Runtime/getRuntime) availableProcessors)} 
      {:name "OS Name:", :value (System/getProperty "os.name")} 
      {:name "OS Arch:", :value (System/getProperty "os.arch")} 
      {:name "User Name:", :value (System/getProperty "user.name")} 
      {:name "Java Version:", :value (System/getProperty "java.version")}) 
      (map #(hash-map :name (str "Disk " (.getAbsolutePath %)), 
          :value (str "Free Space " 
             (float (/ (.getFreeSpace %) (* 1024 1024 1024))) 
             " GB")) 
       (File/listRoots))))