基本上我想做的是打印一个包含键的哈希表,这些键是字符串中的字符,并且这些键的值为1。例如,字符串“ aabbce”应提供字典{:a 1:b 1 :c 1}。 以下是我的尝试,但只显示空的哈希图
(defn isValid [s]
(def dict {})
(map (fn [x] ((assoc dict :x 1))) (seq s))
(println dict)
)
答案 0 :(得分:5)
另一种方法是:
(zipmap (map (comp keyword str) "abc") (repeat 1))
;;=> { :a 1 :b 1 :c 1 }
答案 1 :(得分:2)
您已经违反了Clojure编程的几项准则:
def
。使用let
。要在这里做最后一件事,请使用reduce
而不是map
。 seq
是多余的:map
和reduce
之类的函数会将字符串视为字符序列。所以...
(defn isValid [s]
(reduce (fn [dict x] (assoc dict x 1)) {} s))
例如...
=> (isValid "aabbce" )
{\a 1, \b 1, \c 1, \e 1}
本地dict
和初始值{}
已被reduce
捕获。
为什么要映射到1
?这只是变相的场景吗?如果是这样,...
(defn isValid [s]
(set s))
或者只是...
(def isValid set)
例如
=> (isValid "aabbce" )
#{\a \b \c \e}
您将在函数式编程中找到它。样板代码像奇努克风中的雪一样融化。
最后一个琐碎的抱怨。 isValid
是骆驼的情况。 Clojure约定是
?
跟踪。是valid?
而不是isValid
。
答案 2 :(得分:1)
> (into {} (for [c "aabbce"] [(keyword (str c)) 1]))
{:a 1, :b 1, :c 1, :e 1}
into {} ... sequence of pairs ...
通常是创建哈希图的便捷方法。例如
> (into {} [[:x 1] [:y "foo"]])
{:x 1, :y "foo"}
和for [item collection] [(key-from item) (value-from item)]
是遍历集合以创建键值对列表的一种好方法。
> (for [color ["red" "blue" "green"]] [(clojure.string/upper-case color) (count color)])
(["RED" 3] ["BLUE" 4] ["GREEN" 5])
我发现将它们放在一起通常是创建哈希图的诀窍:
> (into {} (for [color ["red" "blue" "green"]] [(clojure.string/upper-case color) (count color)]))
{"RED" 3, "BLUE" 4, "GREEN" 5}
答案 3 :(得分:0)
有很多方法可以利用Clojure核心库中的大量功能来实现此功能。这是Clojure的每个新开发人员都会遇到的常见问题之一:您认为您需要自己编写一个函数,但是实际上已经存在一些东西,只是您还不知道它的名字,所以{{3 }}可能会派上用场。
让我们从字符串aabbce
开始。您想删除重复项,因此(set "aabbce")
会将字符串作为字符集读取,并从中创建一个字符集。您可以使用map
函数获取每个字符并将其变成关键字。问题在于keyword
函数使用字符串而不是字符,因此我们需要首先在每个字符上使用str
。
一旦我们有了一系列关键字,构造地图的一种简单方法就是使用frequencies
函数,它将使用关键字作为关键字,为关键字集合中的每个元素创建一个哈希图,以及它作为值出现在集合中的次数,并且由于我们已经删除了重复项,因此可以保证每个值都只是1
。
将所有内容放在一起:
(defn is-valid? [s]
(frequencies
(map (comp keyword str) ;; Turns \a into :a for every letter in the set
(set s)))) ;; remove duplicates, yields: (\a, \b, \c, \e)
;; or, using the ->> macro:
(defn is-valid? [s]
(->> (set s) ;; turn string into set of chars
(map (comp keyword str)) ;; turn chars into keywords
frequencies)) ;; compute occurrences hash-map
;; (println (is-valid? "aabbce"))
;; => {:a 1, :b 1, :c 1, :e 1}
现在,名称 isValid 表示您希望将此函数用作谓词(例如,根据输入内容返回true
或false
)。也许想构建一个函数来检查字符串是否由某些字母组成?