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
Dictionary Clojure中的映射_Dictionary_Clojure - Fatal编程技术网

Dictionary Clojure中的映射

Dictionary Clojure中的映射,dictionary,clojure,Dictionary,Clojure,如何让这段代码正常工作?它应该输出四个索引号,后跟从地图中随机选择的名称 (def persons {0 "name1" 1 "name2" 2 "name3"}) (map #(println (str %1 ": " %2)) (iterate inc 0) (persons (rand-int 3))) 请不要建议其他方法,但请更正我的代码,如果你知道应该如何更正它。 它应该输出如下内容: 0:name2,1:name3,2:name1代码中的问题(persons(rand int 3)

如何让这段代码正常工作?它应该输出四个索引号,后跟从地图中随机选择的名称

(def persons {0 "name1" 1 "name2" 2 "name3"})
(map #(println (str %1 ": " %2)) (iterate inc 0) (persons (rand-int 3)))
请不要建议其他方法,但请更正我的代码,如果你知道应该如何更正它。 它应该输出如下内容:
0:name2,1:name3,2:name1

代码中的问题
(persons(rand int 3))
从map中生成一个随机值,如“name3”,map将其视为一个字符序列
(\n\a\m\e\3)

只需将其包装以调用几次:

(重复4#(个人(兰德国际3))

正确且更干净的方法:

(dotimes [i 4]
  (println (str i ":" (rand-nth (vals persons)))))
  • 如果需要副作用(打印),请使用
    dotimes
    而不是
    map
  • 使用
    (rand nth(vals persons))
    而不是
    (persons(rand int 3))
    ,如果地图增长并成为100个元素,则
    rand nth
    仍会按预期运行,而
    rand int
    则基于地图大小

    • 这里有几点需要注意:

    • 如果您想遍历一系列内容并执行一些包含副作用的操作(如打印),则应使用
      doseq
      而不是map

    • 如果你在处理一个映射,那么你给
      map
      doseq
      的函数应该有一个参数,一个MapEntry——有点像一个包含键和值的两项列表。您可以使用解构来获取键和值

    • 您可以这样做:

      (def persons {0 "name1" 1 "name2" 2 "name3"})
      
      (doseq [[i name] persons]
        (println (str i ": " name)))
      

      这并没有抓住你试图做的事情的随机性,但为此,我遵从@mishadoff的回答。

      我强烈建议“保持简单”,如下所示:

      (def persons {0 "name1" 1 "name2" 2 "name3"})
      (let [names       (vals persons)
            names-shuf  (shuffle names)
            idx         (range (count names)) ]
        (doseq [ii idx]
          (println (str ii ": " (nth names-shuf ii)))))
      
      产生:

      ~/clj > lein run
      0: name2
      1: name1
      2: name3
      

      或类似(每次都不同)。请注意,我们在这里使用shuffle,以确保映射中每个名称都有一个结果

      map
      接受一个函数和一个或多个集合。您为它提供了两个集合:一个惰性序列(
      (iterate inc 0)
      )和一个字符串(
      (persons(rand int 3))
      )。因此,您不是按随机顺序打印名称,而是按随机选择的字符串的顺序打印字符

      我想你应该给它一组随机的名字。比如说,你想要的是:

      (def persons {0 "name1" 1 "name2" 2 "name3"})
      (def randomnames 
        (letfn [(makenames [] 
                  (lazy-seq (cons (persons (rand-int 3)) 
                                  (makenames))))]
          (makenames)))
      (map #(println (str %1 ": " %2)) (take 3 (iterate inc 0)) (take 3 randomnames))
      

      上述解决方案打印带有替换的随机名称;不用替换的话做起来会更复杂,但你明白了。该缺陷是,当您确实需要一组随机人(比如向量)时,您使用随机人作为映射的第二个参数。

      这是唯一正确使用
      doseq
      的解决方案,并且还显示了一个随机打印带有替换的名称的解决方案。