2011-06-06 30 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))))