Clojure 构建一个地图列表

Clojure 构建一个地图列表,clojure,Clojure,首先,我是个初学者,我的英语很差 假设您有一个函数,用于返回包含各种信息的映射列表(在本例中为Systeminformation) 我已经想出了下面的例子,但它似乎是错误的,对我来说过于复杂 我的问题是,‘for[disk(File/listRoots)’已经返回了一个列表,我必须合并这两个列表以获得所需的输出,因此必须存在更好的解决方案 我希望你们中有人能启发我如何以一种更“Clojure”的方式来做这件事 (import [java.lang Runtime System] [java.io

首先,我是个初学者,我的英语很差

假设您有一个函数,用于返回包含各种信息的映射列表(在本例中为Systeminformation)

我已经想出了下面的例子,但它似乎是错误的,对我来说过于复杂

我的问题是,‘for[disk(File/listRoots)’已经返回了一个列表,我必须合并这两个列表以获得所需的输出,因此必须存在更好的解决方案

我希望你们中有人能启发我如何以一种更“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")}))))
提前谢谢

Markus

由于您使用(for…)转换每个元素,映射似乎是一个更符合逻辑的选择。您无法真正避免合并两个列表,因为一个是“固定”的,另一个是稍后从文件列表生成的

使用(.methodName object)而不是(.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))))

您还可以使用小的
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)))])))

很酷,我不知道list*helper,这正是我要找的:)+1对于get sysinfo映射建议:我认为这是为这个问题构建数据的最自然的方法