我想知道如何转换
vector [1 2 3 :a :b :c :A :B :C]
到
[ {:index 1 :lower :a :upper :A} {:index 2 :lower :b :upper :B} {:index 3 :lower :c :upper :C} ] ?
向量可以是[1 2 3 4:a:b:c:d:A:B:C:D]
或者如果没有简单的方法,有没有一种转换方法
[{:index 1} {:index 2} {:index 3}] [{:lower :a} {:lower :b} {:lower :c}] [{:upper :A} {:upper :B} {:upper :C}]
到
[{:index 1 :lower :a :upper :A} {:index 2 :lower :b :upper :B} {:index 3 :lower :c :upper :C}]
谢谢!
答案 0 :(得分:1)
因此,总的来说,当遇到这样的问题时,我会去上游并修复输入格式。一个由任意部分串联而成的向量没有任何意义。为了给出答案,让我们假设这是不可能的。
首先,我们定义一个辅助函数来创建结果图:
(defn make-result [i l u]
{:index i :lower l :upper u})
然后,我们只需要将此函数映射到三个子序列上即可:
(defn input->output [i]
(apply map make-result (partition (/ (count i) 3) i)))
我们需要使用apply来生成要用作map参数的子序列序列(请记住,函数arity应该与您传递给map的序列数相匹配-我们的助手很方便地做到这一点)。 / p>
这将适用于上面给出的两个向量。
(input->output [1 2 3 :a :b :c :A :B :C])
({:index 1, :lower :a, :upper :A} {:index 2, :lower :b, :upper :B} {:index 3, :lower :c, :upper :C})
(input->output [1 2 3 4 :a :b :c :d :A :B :C :D])
({:index 1, :lower :a, :upper :A} {:index 2, :lower :b, :upper :B} {:index 3, :lower :c, :upper :C} {:index 4, :lower :d, :upper :D})
如果向量采用其他格式,则可能会令您感到惊讶或失望-也许是为了进行一些输入验证。
答案 1 :(得分:1)
(let [ks [:index :lower :upper]
xs [1 2 3 :a :b :c :A :B :C]]
(->> xs
(partition (/ (count xs) (count ks)))
(apply map vector)
(mapv zipmap (repeat ks))))
工作原理:
我们首先通过partition
count
引导向量:
(partition (/ (count xs) (count ks)) xs)=> ((1 2 3) (:a :b :c) (:A :B :C))
然后转置矩阵:
(apply map vector *1)=> ([1 :a :A] [2 :b :B] [3 :c :C])
最后zipmap
,并为每行提供键:
(mapv zipmap (repeat ks) *1)=> [{:index 1, :lower :a, :upper :A} {:index 2, :lower :b, :upper :B} {:index 3, :lower :c, :upper :C}]
答案 2 :(得分:0)
如果您可以提供键值列表,如下所示(为提高可读性而设置的格式):
(def items [[{:index 1} {:index 2} {:index 3}]
[{:lower :a} {:lower :b} {:lower :c}]
[{:upper :A} {:upper :B} {:upper :C}]])
然后您可以使用以下内容:
(apply map merge items)
;; returns ({:index 1, :lower :a, :upper :A} {:index 2, :lower :b, :upper :B} {:index 3, :lower :c, :upper :C})
这可以通过使用map
函数来merge
3个集合中的各个哈希图来实现。首先,将每个集合的第一个元素合并在一起,生成元素{:index 1, :lower :a, :upper :A}
,然后将每个集合的第二个元素合并,依此类推。
由于map merge
的参数是一个集合,因此您需要使用apply
来提供map
的参数。
答案 3 :(得分:0)
我不是Clojure专家,但这也许会有所帮助:
; your data
(def x [1 2 3 :a :b :c :A :B :C])
; resolve symbols and numbers to strings
(def xa (map (fn [e] (if (keyword? e) (name e) (str e))) x))
; split into three sequences and zip this lists together
(let [xan (filter (fn [e] (not (empty? (re-matches #"[0-9]" e)))) xa)
xaa (filter (fn [e] (not (empty? (re-matches #"[a-z]" e)))) xa)
xaA (filter (fn [e] (not (empty? (re-matches #"[A-Z]" e)))) xa)]
(map-indexed (fn [i e] {:index e :lower (nth xaa i) :upper (nth xaA i)}) xan ))
您只需构建三个序列并对其进行迭代,然后使用索引访问另一个序列中的相应元素。