1

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

我想实现下面交错生成的序列,但不需要以有限数量的映射形式进行编码。

(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 参数的作用类似于序列选择器,而不是序列中的元素选择器。我想从每个序列中提取几个元素。如何从每个序列中提取元素?

谢谢你。

4

3 回答 3

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")
于 2012-04-19T18:26:48.580 回答
1

for您可以使用and更简洁地执行此操作partition

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"))

这也将保留原始分组。

于 2012-04-20T14:17:16.743 回答
0

我会这样做:

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

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

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

  • “apply concat”类似于“flatten”,但只有一层深

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

于 2012-04-20T17:28:59.270 回答