Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure中跨分区的分区?_Clojure_Lazy Sequences - Fatal编程技术网

Clojure中跨分区的分区?

Clojure中跨分区的分区?,clojure,lazy-sequences,Clojure,Lazy Sequences,以下是一些值。每个值都是升序(或分组)值的序列 我可以按值对它们进行分区 => (map (partial partition-by first) input-vals) ((([1 :a] [1 :b]) ([2 :c]) ([3 :d] [3 :e])) (([1 :f]) ([2 :g] [2 :h] [2 :i]) ([3 :j] [3 :k])) (([1 :l]) ([3 :m]))) 但我得到了3个分区序列。我想要一个单独的分区组序列 我想做的是返回一个单独的惰性序列

以下是一些值。每个值都是升序(或分组)值的序列

我可以按值对它们进行分区

=> (map (partial partition-by first) input-vals)
   ((([1 :a] [1 :b]) ([2 :c]) ([3 :d] [3 :e])) (([1 :f]) ([2 :g] [2 :h] [2 :i]) ([3 :j] [3 :k])) (([1 :l]) ([3 :m])))
但我得到了3个分区序列。我想要一个单独的分区组序列

我想做的是返回一个单独的惰性序列(可能是)惰性序列,它们是连接的各个分区。e、 g.我想制作这个:

((([1 :a] [1 :b] [1 :f] [1 :l]) ([2 :c] [2 :g] [2 :h] [2 :i]) ([3 :d] [3 :e] [3 :j] [3 :k] [3 :m])))
请注意,并非所有值都出现在所有序列中(第三个向量中没有
2

这当然是我问题的简化。真正的数据是一组来自非常大的文件的惰性流,因此无法实现任何功能。但我认为解决上述问题的办法就是解决我的问题


请随意编辑标题,我不太确定如何表达它。

我不确定是否在跟踪,但您可以更改结果序列,例如:

(flatten (partition-by identity (first input-vals)))
clojure.核心/扁平化
([x])
获取顺序事物(列表、向量等)的任何嵌套组合 等)并将其内容作为单一的平面序列返回。
(展平为零)返回空序列


你能用它吗?函数来测试一个序列是否懒惰。

我不确定是否遵循了该函数,但您可以更改结果序列,例如:

(flatten (partition-by identity (first input-vals)))
user> (def desired-result '((([1 :a] [1 :b] [1 :f] [1 :l])
                             ([2 :c] [2 :g] [2 :h] [2 :i])
                             ([3 :d] [3 :e] [3 :j] [3 :k] [3 :m]))))
#'user/desired-result

user> (def input-vals [[[1 :a] [1 :b] [2 :c] [3 :d] [3 :e]]
                       [[1 :f] [2 :g] [2 :h] [2 :i] [3 :j] [3 :k]]
                       [[1 :l] [3 :m]]])
#'user/input-vals

user> (= desired-result (vector (vals (group-by first (apply concat input-vals)))))
true
clojure.核心/扁平化
([x])
获取顺序事物(列表、向量等)的任何嵌套组合 等)并将其内容作为单一的平面序列返回。
(展平为零)返回空序列

你能用它吗?函数来测试序列是否懒惰

user> (def desired-result '((([1 :a] [1 :b] [1 :f] [1 :l])
                             ([2 :c] [2 :g] [2 :h] [2 :i])
                             ([3 :d] [3 :e] [3 :j] [3 :k] [3 :m]))))
#'user/desired-result

user> (def input-vals [[[1 :a] [1 :b] [2 :c] [3 :d] [3 :e]]
                       [[1 :f] [2 :g] [2 :h] [2 :i] [3 :j] [3 :k]]
                       [[1 :l] [3 :m]]])
#'user/input-vals

user> (= desired-result (vector (vals (group-by first (apply concat input-vals)))))
true
我稍微更改了输入VAL,以更正我认为是印刷错误的内容,如果不是错误,我可以更新代码以适应不太规则的结构

使用
->
(thread last)宏,我们可以获得更可读的等效代码:

user> (= desired-result
         (->> input-vals
           (apply concat)
           (group-by first)
           vals
           vector))
true
我稍微更改了输入VAL,以更正我认为是印刷错误的内容,如果不是错误,我可以更新代码以适应不太规则的结构

使用
->
(thread last)宏,我们可以获得更可读的等效代码:

user> (= desired-result
         (->> input-vals
           (apply concat)
           (group-by first)
           vals
           vector))
true
试试这个恐怖:

(defn partition-many-by [f comp-f s]
  (let [sorted-s (sort-by first comp-f s)
        first-list (first (drop-while (complement seq) sorted-s))
        match-val (f (first first-list))
        remains (filter #(not (empty? %)) 
                        (map #(drop-while (fn [ss] (= match-val (f ss))) %) 
                             sorted-s))]
    (when match-val
      (cons
        (apply concat
          (map #(take-while (fn [ss] (= match-val (f ss))) %)
               sorted-s))
        (lazy-seq (partition-many-by f comp-f remains))))))
可以对其进行改进,以删除双值检查(take-while和drop-while)

用法示例:

(partition-many-by identity [[1 1 1 1 2 2 3 3 3 3] [1 1 2 2 2 2 3] [3]])

=> ((1 1 1 1 1 1) (2 2 2 2 2 2) (3 3 3 3 3 3))
试试这个恐怖:

(defn partition-many-by [f comp-f s]
  (let [sorted-s (sort-by first comp-f s)
        first-list (first (drop-while (complement seq) sorted-s))
        match-val (f (first first-list))
        remains (filter #(not (empty? %)) 
                        (map #(drop-while (fn [ss] (= match-val (f ss))) %) 
                             sorted-s))]
    (when match-val
      (cons
        (apply concat
          (map #(take-while (fn [ss] (= match-val (f ss))) %)
               sorted-s))
        (lazy-seq (partition-many-by f comp-f remains))))))
可以对其进行改进,以删除双值检查(take-while和drop-while)

用法示例:

(partition-many-by identity [[1 1 1 1 2 2 3 3 3 3] [1 1 2 2 2 2 3] [3]])

=> ((1 1 1 1 1 1) (2 2 2 2 2 2) (3 3 3 3 3 3))

让我们让这变得有趣,并使用无限长的序列作为输入

(def twos (iterate #(+ 2 %) 0))
(def threes (iterate #(+ 3 %) 0))
(def fives (iterate #(+ 5 %) 0))
我们需要懒洋洋地合并它们。让我们要求一个比较器,这样我们也可以应用于其他数据类型

(defn lazy-merge-by
 ([compfn xs ys] 
  (lazy-seq
    (cond
      (empty? xs) ys
      (empty? ys) xs
      :else (if (compfn (first xs) (first ys)) 
              (cons (first xs) (lazy-merge-by compfn (rest xs) ys))
              (cons (first ys) (lazy-merge-by compfn xs (rest ys)))))))
  ([compfn xs ys & more] 
   (apply lazy-merge-by compfn (lazy-merge-by compfn xs ys) more)))
试验

(取15(通过 (0 0 0 2 3 4 5 6 6 8 9 10 10 12 12)
如果需要,我们可以(惰性地)按值进行分区

(take 10 (partition-by identity (lazy-merge-by < twos threes fives)))
;=> ((0 0 0) (2) (3) (4) (5) (6 6) (8) (9) (10 10) (12 12))
(取10(按标识划分(按 ((0 0 0) (2) (3) (4) (5) (6 6) (8) (9) (10 10) (12 12))
现在,回到示例输入

(partition-by first (apply lazy-merge-by #(<= (first %) (first %2)) input-vals))
;=> (([1 :a] [1 :b] [1 :f] [1 :l]) ([2 :c] [2 :g] [2 :h] [2 :i]) ([3 :d] [3 :e] [3 :j] [3 :k] [3 :m]))
([1:a][1:b][1:f][1:l])([2:c][2:g][2:h][2:i])([3:d][3:e][3:j][3:k][3:m])

根据需要,减少一组无关的外圆括号。

让我们将其变得有趣,并使用无限长的序列作为输入

(def twos (iterate #(+ 2 %) 0))
(def threes (iterate #(+ 3 %) 0))
(def fives (iterate #(+ 5 %) 0))
(partition-by first (sort-by first (mapcat identity input-vals)))
我们需要惰性地合并它们。让我们请求一个比较器,这样我们也可以应用于其他数据类型

(defn lazy-merge-by
 ([compfn xs ys] 
  (lazy-seq
    (cond
      (empty? xs) ys
      (empty? ys) xs
      :else (if (compfn (first xs) (first ys)) 
              (cons (first xs) (lazy-merge-by compfn (rest xs) ys))
              (cons (first ys) (lazy-merge-by compfn xs (rest ys)))))))
  ([compfn xs ys & more] 
   (apply lazy-merge-by compfn (lazy-merge-by compfn xs ys) more)))
试验

(取15(通过 (0 0 0 2 3 4 5 6 6 8 9 10 10 12 12)
如果需要,我们可以(惰性地)按值进行分区

(take 10 (partition-by identity (lazy-merge-by < twos threes fives)))
;=> ((0 0 0) (2) (3) (4) (5) (6 6) (8) (9) (10 10) (12 12))
(取10(按标识划分(按 ((0 0 0) (2) (3) (4) (5) (6 6) (8) (9) (10 10) (12 12))
现在,回到示例输入

(partition-by first (apply lazy-merge-by #(<= (first %) (first %2)) input-vals))
;=> (([1 :a] [1 :b] [1 :f] [1 :l]) ([2 :c] [2 :g] [2 :h] [2 :i]) ([3 :d] [3 :e] [3 :j] [3 :k] [3 :m]))
([1:a][1:b][1:f][1:l])([2:c][2:g][2:h][2:i])([3:d][3:e][3:j][3:k][3:m])


根据需要减少一组无关的外括号。

这几乎满足了我的要求。我将澄清我的问题(我认为你的答案仍然适用)。但它是懒惰的吗?扁平化将消除输入的所有内部结构,只留下一个简单的数字和关键字序列。@噪音原始问题已被编辑过几次。我很确定我的答案现在已经过时了。公平点,但应该指出,扁平化是一个臭名昭著的问题,这是真正的问题在这方面,展平功能很少是正确的。这几乎满足了我的要求。我会澄清我的问题(我认为你的答案仍然适用)。但它是懒惰的吗?扁平化将消除输入的所有内部结构,只留下一个简单的数字和关键字序列。@噪音原始问题已被编辑过几次。我很确定我的答案现在已经过时了。公平点,但应该指出,扁平化是一个臭名昭著的问题,这是真正的问题在这个问题上,扁平化很少是正确的函数。你知道你对你的问题做了多少更改吗?:pI更改了内容,但没有更改我正在寻找的函数的应用程序。感谢大家的耐心。我试图通过使用简单的值使问题尽可能简单。(还在回复中输入了一个让事情变得混乱的错误)。我试图实现的目标没有改变,但chiron的回答使用了identity,这意味着我必须证明用于分区的投影值(在本例中,首先是
)具有公共值,但这些值本身(
[1:a]
)都是相互独特的。如果你看第一个版本,语义是相同的,只是示例数据不太清楚:所需输出的结构不同-第一个版本的顺序是扁平的,当前似乎是分区的。不管怎样,如果你有第一个,你可以很容易地生成第二个。我认为现在丢失的是
(partition-by first (sort-by first (mapcat identity input-vals)))