如何为第n个实现可变数量的索引

时间:2012-04-19 18:15:34

标签: clojure

我的问题是如何在不知道编译时有多少元素的情况下从序列中提取大量元素。使用部分想到了,但我一直难以拔出元素而不是序列。

我想实现下面交错生成的序列,但不需要编码有限数量的地图形式。

(def s1 [[:000-00-0000 "TYPE 1" "JACKSON" "FRED"]
         [:000-00-0001 "TYPE 2" "SIMPSON" "HOMER"]
         [:000-00-0002 "TYPE 4" "SMITH" "SUSAN"]])

(interleave (map #(nth % 0 nil) s1) 
            (map #(nth % 2 nil) s1) 
            (map #(nth % 3 nil) s1))

(:000-00-0000 "JACKSON" "FRED" 
 :000-00-0001 "SIMPSON" "HOMER" 
 :000-00-0002 "SMITH" "SUSAN")

如果我执行以下操作

(def cols [0 2 3])

(defn f1
    [s1 col]
    (nth s1 col nil))

(map (partial f1 s1) cols)

我得到了

([:000-00-0000 "TYPE 1" "JACKSON" "FRED"]\
 [:000-00-0002 "TYPE 4" "SMITH" "SUSAN"] nil)

我相信我知道为什么会这样。 cols param的作用类似于序列选择器,而不是序列中的元素选择器。我想从每个序列中提取几个元素。如何从每个序列中提取元素?

谢谢。

3 个答案:

答案 0 :(得分:1)

您可以使用get-in函数访问嵌套数据结构,如下所示:

(def cols [0 2 3])

(defn f1 
  [s1 col] 
  (map #(get-in s1 [% col] nil) (range (count s1))))

(apply interleave (map (partial f1 s1) cols))

(:000-00-0000 "JACKSON" "FRED" 
 :000-00-0001 "SIMPSON" "HOMER" 
 :000-00-0002 "SMITH" "SUSAN")

答案 1 :(得分:1)

您可以使用forpartition更简洁地执行此操作:

user> (defn get-cols [s cols] (partition (count cols) (for [ws s c cols] (ws c))))
#'user/get-cols
user> (get-cols [[:000-00-0000 "TYPE 1" "JACKSON" "FRED"]
            [:000-00-0001 "TYPE 2" "SIMPSON" "HOMER"]
            [:000-00-0002 "TYPE 4" "SMITH" "SUSAN"]]
            [0 2 3])
((:000-00-0000 "JACKSON" "FRED") (:000-00-0001 "SIMPSON" "HOMER") (:000-00-0002 "SMITH" "SUSAN"))

这也将保留原始分组。

答案 2 :(得分:0)

我就是这样做的:

(apply concat (map (juxt first #(nth % 2) #(nth % 3)) s1))

这首先将s1中的列收集到中间向量中,然后将这些向量展平一级,从而得到结果。

这里有两个非常方便的功能:

  • “apply concat”就像“flatten”,但只有一层深

  • juxt返回一个函数A,它将传递给juxt(必须是函数)的参数应用于传递给A的值并返回结果的向量。