如何防止此clojure函数返回列表
我想在clojure中编写一个函数,它将返回一个映射,并给出一个形式为“key1$value1,key2$value2”的字符串。我想到了这个如何防止此clojure函数返回列表,clojure,Clojure,我想在clojure中编写一个函数,它将返回一个映射,并给出一个形式为“key1$value1,key2$value2”的字符串。我想到了这个 (defn get-map "Returns a map of key value pairs from a string formatted in the form 'key1$value1,key2$value2'" [line] (let [result {}] (for [item (split line #",")]
(defn get-map
"Returns a map of key value pairs from a string formatted in the form 'key1$value1,key2$value2'"
[line]
(let [result {}]
(for [item (split line #",")]
(let [pair (split item #"\$")]
(assoc result (nth pair 0)
(if (= (.size pair) 2) (nth pair 1) ""))))))
尽管它可以工作,但这段代码的唯一问题是它返回列表中的映射
=>(get-map "key1$value1,key2,value2")
({"key1" "value1"} {"key2" "value2"})
我试图将结果作为第一个let表单的最后一个表达式返回,但结果是一个空映射
(defn get-map
"Returns a map of key value pairs from a string formatted in the form 'key1$value1,key2$value2'"
[line]
(let [result {}]
(for [item (split line #",")]
(let [pair (split item #"\$")]
(assoc result (nth pair 0)
(if (= (.size pair) 2) (nth pair 1) ""))))
result))
=>(get-map "key1$value1,key2,value2")
{}
两个问题-
(defn get-map
"Returns a map of key value pairs from a string formatted in the form 'key1$value1,key2$value2'"
[line]
(->> (clojure.string/split line #",")
(mapcat #(clojure.string/split % #"\$"))
(apply hash-map)))
user> (get-map "key1$value1,key2$value2")
{"key1" "value1", "key2" "value2"}
关于问题1的回答/提示:
For始终返回一个序列。这是Clojure中的列表理解
关于问题2的回答/提示:
Clojure的数据结构是不可变的。这意味着关联现有映射不会改变现有映射,而是返回一个新映射
关于问题1的回答/提示:
For始终返回一个序列。这是Clojure中的列表理解
关于问题2的回答/提示:
Clojure的数据结构是不可变的。这意味着在现有映射上关联不会改变现有映射,而是返回一个新映射。for的
表单不支持延迟列表理解,因此不适合按顺序更新结构。您可以使用for
生成配对列表,并使用reduce
将它们打包到地图中。或者,在
中使用,这会减少:
(defn get-map [line]
(into {}
(for [item (split line #",")]
(split item #"\$"))))
使用re-seq
的另一种可能实现:
(defn get-map [s]
(into {} (map #(subvec % 1) (re-seq #"([^\$]+)\$([^,]+),*" s))))
for
表单不支持惰性列表理解,因此不适合按顺序更新结构。您可以使用for
生成配对列表,并使用reduce
将它们打包到地图中。或者,在
中使用,这会减少:
(defn get-map [line]
(into {}
(for [item (split line #",")]
(split item #"\$"))))
使用re-seq
的另一种可能实现:
(defn get-map [s]
(into {} (map #(subvec % 1) (re-seq #"([^\$]+)\$([^,]+),*" s))))
在Clojure中,for
不是循环,而是列表理解。基本上,它需要你的每一个项目
集合,并将其绑定到指定的任何名称(本例中为item
),然后进行计算
表达式(let[pair…
,在本例中)。每个计算的结果都以
顺序
例如:
(for [item (split "key1$value1,key2$value2" #",")]
item)
;returns: ("key1$value1" "key2$value2")
在函数中,实际创建列表的是for
。由let
绑定的名称是不可变的
所以每次for
计算其表达式时result
仍然是一个空映射
地图列表,每个地图中有一个条目
下面是一种生成键值对列表的方法,该列表使用了nth的未找到功能
要在缺少$时提供默认值,请执行以下操作:
(for [item (split "key1$value1,key2$value2,key3" #",")]
(let [pair (split item #"\$")]
[(nth pair 0) (nth pair 1 "")]))
;returns: (["key1" "value1"] ["key2" "value2"] ["key3" ""])
然后您可以使用转换为将其转换为地图。以下是完整的功能:
(defn get-map
"Returns a map of key value pairs from a string formatted in the form 'key1$value1,key2$value2'"
[line]
(into {}
(for [item (split line #",")]
(let [pair (split item #"\$")]
[(nth pair 0) (nth pair 1 "")]))))
在Clojure中,for
不是一个循环,而是一个列表理解。基本上,它接受您的
集合,并将其绑定到指定的任何名称(本例中为item
),然后进行计算
表达式(let[pair…
,在本例中)。每个计算的结果都以
顺序
例如:
(for [item (split "key1$value1,key2$value2" #",")]
item)
;returns: ("key1$value1" "key2$value2")
在函数中,实际创建列表的是for
。由let
绑定的名称是不可变的
所以每次for
计算其表达式时result
仍然是一个空映射
地图列表,每个地图中有一个条目
下面是一种生成键值对列表的方法,该列表使用了nth的未找到功能
要在缺少$时提供默认值,请执行以下操作:
(for [item (split "key1$value1,key2$value2,key3" #",")]
(let [pair (split item #"\$")]
[(nth pair 0) (nth pair 1 "")]))
;returns: (["key1" "value1"] ["key2" "value2"] ["key3" ""])
然后您可以使用转换为将其转换为地图。以下是完整的功能:
(defn get-map
"Returns a map of key value pairs from a string formatted in the form 'key1$value1,key2$value2'"
[line]
(into {}
(for [item (split line #",")]
(let [pair (split item #"\$")]
[(nth pair 0) (nth pair 1 "")]))))