【发布时间】:2014-11-18 14:54:01
【问题描述】:
我有这个字符串向量:
["a1" "b3" "q9" "c4" "l2" "b3"]
如果给定一个字母,我想返回相应的数字。
所以,如果我正在搜索字母 q,我想返回 9。如果我正在搜索字母 c,我想返回 4。
我也不必使用向量来存储字符串;我只是认为这是最有意义的数据结构。
我曾想过使用 zipmap 创建一个我可以搜索的地图,但我不确定如何将字符串分开。
【问题讨论】:
我有这个字符串向量:
["a1" "b3" "q9" "c4" "l2" "b3"]
如果给定一个字母,我想返回相应的数字。
所以,如果我正在搜索字母 q,我想返回 9。如果我正在搜索字母 c,我想返回 4。
我也不必使用向量来存储字符串;我只是认为这是最有意义的数据结构。
我曾想过使用 zipmap 创建一个我可以搜索的地图,但我不确定如何将字符串分开。
【问题讨论】:
你可以这样做:
(apply hash-map (mapcat seq ["a1" "b3" "q9" "c4" "l2" "b3"]))
=> {\a \1, \b \3, \c \4, \l \2, \q \9}
您可以使用一个函数来代替seq,将您的字符串转换为您想要的类型的东西对,如果您希望使用字符以外的东西。
【讨论】:
这非常低效,哈希映射为排序映射提供更快的访问(log32N 跃点)与(logN 跃点)。见http://clojuredocs.org/clojure.core/hash-map和http://clojure.org/data_structures
为完成而编辑:
(def v ["a1" "b3" "q9" "c4" "l2" "b3"])
(def my-map (apply hash-map (mapcat #(vector (subs % 0 1) (subs % 1)) v)))
(my-map "a")
=> 1
【讨论】:
mapcat的建议,再次编辑以显示更短的版本
将矢量转换成地图确实是个好主意。您可以使用subs 将琴弦拉开。 (subs s 0 1) 将字符串 s 的第一个字符作为字符串返回,(subs s 1) 返回其余字符。
(def a-list ["a1" "b3" "q9" "c4" "l2" "b3"])
(def a-map
(into {} (map (fn [s] [(subs s 0 1) (Integer/valueOf (subs s 1))])
a-list)))
;; => {"a" 1, "b" 3, "q" 9, "c" 4, "l" 2}
(get a-map "q")
;; => 9
【讨论】:
(subs s 0 1) 返回字符串的第一个字符。不完全的。它返回一个字符串,而不是一个字符。 (first s) 返回第一个字符。
(into {} ...) 返回的映射值。 (a-map "q") 与 (get a-map "q") 相同 - 它返回映射 a-map 中键 "q" 的值。
您可以通过将字符串解构为将值简化为映射的函数的参数,从而将字母字符与数字字符分开。然后使用搜索到的字符
(defn search-character-vector [v ch]
((reduce (fn [m [c n]] (assoc m c n)) {} v) ch)
)
(search-character-vector ["a1" "b3" "q9" "c4" "l2" "b3"] \q)
这将返回链接到字符 \q 的字符 \9
【讨论】:
你可以使用zipmap重新查找。
(def strings
["a1" "b3" "q9" "c4" "l2" "b3"])
(defn from-letter [l coll]
(let [m (zipmap
(map #(re-find #"[a-zA-Z]{1}" %) coll)
(map #(re-find #"\d+" %) coll))]
(try
(Integer/parseInt (get m l))
(catch Exception ex nil))))
user> (from-letter "a" strings)
1
user> (from-letter "b" strings)
3
user> (from-letter "c" strings)
4
【讨论】: