Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何防止此clojure函数返回列表_Clojure - Fatal编程技术网

如何防止此clojure函数返回列表

如何防止此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 #",")]

我想在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 #",")]
      (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")
{}
两个问题-

  • 我应该如何修改函数以仅返回映射,而不返回列表包装器
  • 为什么作为第一个let表单的最后一个表达式返回结果会返回空映射
  • 此外,如果您有以更好、更惯用的clojure方式编写相同函数的建议,我们将不胜感激

    (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 "")]))))