如何在Clojure中的哈希映射上通过索引获得随机访问?

nuv*_*vio 3 indexing clojure hashmap random-access

我想MAX_OPERATIONS从一个账户到另一个账户进行一定数量的资金转账.帐户作为refs存储在散列图调用程序中my-map(int account-id,double balance).

汇款需要从散列图"随机指数",并将它作为account-fromtransfer.account-destination并且amount都应该修复.

不幸的是我不能让它发挥作用.

(defn transfer [from-account to-account amount]
  (dosync
    (if (> amount @from-account)
      (throw (Exception.  "Not enough money")))
    (alter from-account - amount)
    (alter to-account + amount)))

(defn transfer-all []
  (dotimes [MAX_OPERATIONS]
    (transfer (get mymap (rand-int[MAX_ACCOUNT]) :account-id) account-destination amount)))
Run Code Online (Sandbox Code Playgroud)

mik*_*era 5

我立刻看到了几个问题:

你的dotimes语法错误,你需要包含一个循环变量.就像是:

(dotimes [i MAX_OPERATIONS]
   ....)
Run Code Online (Sandbox Code Playgroud)

另外rand-int只需要一个整数参数raher而不是vector,如:

(rand-int MAX_ACCOUNT)
Run Code Online (Sandbox Code Playgroud)

另外,我不确定你的(获得......)电话是否正在按你的意愿行事.如当前所写,:account-id如果找不到随机生成的整数键,它将返回关键字,这将导致问题,因为传递函数需要两个ref作为来自帐户和帐户.

作为更一般的建议,您应该尝试在REPL中逐位编码,检查每个部分是否按预期工作.这通常是在Clojure中开发的最佳方式 - 如果你在没有测试的情况下一次编写太多代码,那么它可能包含多个错误,你可能会试图找到问题的根源而迷失方向.


Art*_*ldt 5

地图不会植入第n个,因此您需要使用一个实际植入的中间结构. 你可以根据你想要的输出来制作一个只有键或整个地图条目的seq.我喜欢使用rand-nth这种东西因为它读得很好

你可以得到一个nth能够seq的键,然后随机使用一个:

user> (def mymap {:a 1, :b 2, :c 3})
#'user/mymap
user> (get mymap (rand-nth (keys mymap)))
1
user> (get mymap (rand-nth (keys mymap)))
1
user> (get mymap (rand-nth (keys mymap)))
3
Run Code Online (Sandbox Code Playgroud)

或者你可以将地图变成一个nth能量矢量,然后随机抓取一个

user> (rand-nth (vec mymap))
[:a 1]
user> (rand-nth (vec mymap))
[:c 3]
Run Code Online (Sandbox Code Playgroud)