假设我们有一个具有以下结构的映射m:
{:a (go "a")
:b "b"
:c "c"
:d (go "d")}如图所示,m有四个键,其中两个包含通道。
问题:如何编写一个通用函数(或宏?) cleanse-map,它接受像m这样的映射并输出它的无通道版本(在这种情况下,它将是{:a "a" :b "b" :c "c" :d "d"})?
对于这个问题,一个很好的帮助函数可能如下:
(defn chan? [c]
(= (type (chan)) (type c)))cleanse-map的返回值(或它称为什么)本身是否是一个通道也不重要。即:
`(cleanse-map m) ;=> (go {:a "a" :b "b" :c "c" :d "d"})发布于 2016-03-10 05:20:37
局限性 of core.async使cleanse-map的实现不那么简单。但以下一项应能发挥作用:
(defn cleanse-map [m]
(let [entry-chs (map
(fn [[k v]]
(a/go
(if (chan? v)
[k (a/<! v)]
[k v])))
m)]
(a/into {} (a/merge entry-chs))))基本上,这里所做的是:
go-block中提取它。merge-d到单个的.在这一步之后,您将拥有一个包含地图条目集合的通道。a/into步骤)。发布于 2016-03-10 05:30:29
(ns foo.bar
(:require
[clojure.core.async :refer [go go-loop <!]]
[clojure.core.async.impl.protocols :as p]))
(def m
{:a (go "a")
:b "b"
:c "c"
:d (go "d")
:e "e"
:f "f"
:g "g"
:h "h"
:i "i"
:j "j"
:k "k"
:l "l"
:m "m"})
(defn readable? [x]
(satisfies? p/ReadPort x))
(defn cleanse-map
"Takes from each channel value in m,
returns a single channel which will supply the fully realized m."
[m]
(go-loop [acc {}
[[k v :as kv] & remaining] (seq m)]
(if kv
(recur (assoc acc k (if (readable? v) (<! v) v)) remaining)
acc)))
(go (prn "***" (<! (cleanse-map m))))=>“*”{:m "m",e "e",:l "l",K "k",:g "g",:c "c",J "j",:h "h",:b "b",d "d",:f "f",:i "i",a "a"}
https://stackoverflow.com/questions/35907709
复制相似问题