Clojure函数在集合中产生“内部笛卡尔积”

时间:2013-06-16 18:54:04

标签: clojure

鉴于清单:

'( [:a [:a1 :a2]]  [:b [:b1 :b2 :b3]] )

如何生成列表:

'( [:a :a1] [:a :a1] [:b :b1] [:b :b2] [:b :b3] )

(某种元素扩展笛卡尔积与1级扁平化相结合)

我能想到的最好的是:

(apply concat (map #(for [v (second %)] (vector (first %) v)) TheList))

看起来过于复杂;什么是实现它的更惯用的方式?

此外,在尝试在列表中执行此类元素扩展笛卡尔产品时,应该考虑哪些函数系列? (我完全不知道如何形容它。)

2 个答案:

答案 0 :(得分:5)

另一个:

(for [[x inner-xs] theList
      inner-x      inner-xs]
  [x inner-x])

for对嵌套集合和平面结果非常有用。

答案 1 :(得分:3)

我会按以下方式进行。它使用destructuring和mapcat来简化表达式:

(mapcat (fn [[a b]] (map #(vector a %) b)) theList)

一般来说,mapcat(或其他语言中的flatmap / collect / selectmany)适用于处理在转换它们时要展平的嵌套集合。