2014-07-16 53 views
1

来自OOP,我在调整Clojure的不变性方面遇到了一些麻烦。如何从Clojure中的文件中读取多个变量?

我想要做的是从文件中获取一些变量,并将每个变量及其数据存储到一张地图中。

换句话说,我想从文本文件中“提取”地图。

作为一个例子,该文件是这样的:

username: michael 
password: foo123 
email: [email protected] 

我的问题是,我该如何转换上面的文件转换成地图是这样的:(?)

{:username "michael", :password "foo123", :email "[email protected]"} 

这就是我有这么远,但我不知道如何让多个变量:

(with-open [rdr (reader "/path/to/file.txt")] 
    (doseq [line (line-seq rdr)] 
    // make map here somehow?)) 

回答

4

试试这个:

(->> (clojure.string/split (slurp "yourfile.txt") #"\n") 
    (map #(clojure.string/split % #":")) 
    (map (fn [[k v]] [(keyword k) v])) 
    (into {})) 

slurp函数读取文件并返回一个文件内容的字符串。将文本文件读入字符串很有用。之后,将字符串拆分为\n,这会反转一系列字符串。然后分割每个字符串:

您可以检查REPL每一步,看看每一步的结果,就像这样:

user=> (->> (clojure.string/split (slurp "yourfile.txt") #"\n")) 
["username: michael" "password: foo123" "email: [email protected]"] 
user=> (->> (clojure.string/split (slurp "yourfile.txt") #"\n") 
      (map #(clojure.string/split % #":\s*"))) 
(["username" "michael"] ["password" "foo123"] ["email" "[email protected]"]) 
user=> (->> (clojure.string/split (slurp "yourfile.txt") #"\n") 
      (map #(clojure.string/split % #":\s*")) 
      (map (fn [[k v]] [(keyword k) v]))) 
([:username "michael"] [:password "foo123"] [:email "[email protected]"]) 
user=> (->> (clojure.string/split (slurp "yourfile.txt") #"\n") 
      (map #(clojure.string/split % #":\s*")) 
      (map (fn [[k v]] [(keyword k) v])) 
      (into {})) 
{:username "michael", :password "foo123", :email "[email protected]"} 
+0

完全,工作,教了我不少!感谢您的帮助。 –

+2

为了摆脱每个值的初始空间,在'#“上分割:\ s *”' - 一个冒号后跟(可选)任意数量的空格。 –

+0

@DaveYarwood哎呀。我没有注意到冒号后的空白处。我更新了答案。 – ntalbs