【问题标题】:How To Turn a Reduce-Realized Sequence Back Into Lazy Vector Sequence如何将减少实现的序列转回惰性向量序列
【发布时间】:2012-04-12 22:06:13
【问题描述】:

当我在这个函数中运行一个 221 行的 .csv 文件(使用 clojure-csv 解析)时

(defn test-key-inclusion
    "Accepts csv-data param and an index, a second csv-data param and an index,
     and searches the second csv-data instances' rows (at index) to see if
     the first file's data is located in the second csv-data instance."

    [csv-data1 pkey-idx1 csv-data2 pkey-idx2 lnam-idx fnam-idx]

    (reduce
        (fn [out-log csv-row1]
            (let [cmp-val (nth csv-row1 pkey-idx1 nil)
                  lnam (nth csv-row1 lnam-idx nil)
                  fnam (nth csv-row1 fnam-idx)
                  temp-rc (first (key-pres? cmp-val pkey-idx2 csv-data2))]

            (concat out-log (sorted-map cmp-val (vector lnam fnam)))))
         {}
         csv-data1))

然后打印结果,一切都很好。

如果我通过上面的函数运行一个 2672 行的 .csv 文件——也用 clojure-csv 解析——然后尝试打印它,我得到一个堆栈溢出错误——线程“main”java.lang 中的异常.StackOverflowError

所以我的问题是:

1) 是否应该在lazy-seq 中封装对这个函数的调用来解决我的问题?

2) 我不想要一个列表,所以将把lazy-seq 调用包装在一个 vec 回合中 我的序列回到一个向量而没有意识到内存中的整个序列,那就是让惰性序列再次变得不惰性?

谢谢。

【问题讨论】:

  • 您想要concat 还是mergeconcat 没有多大意义——你可以映射而不是减少。 reduce 本身就是懒惰的。我对这个问题很困惑......
  • 我想获取一堆 csv 行,然后将它们(列宽减小)返回到 clojure-csv 解析的相同类型的数据。我使用 concat 而不是 conj 所以空行将是最后一个。
  • 那么你为什么使用reduce而不是map?听起来你最终要在 reduce 中重写 map(这是可能的 - reduce 更通用 - 但不是一个好主意)。
  • 在某些情况下,我一直无法使用 map;减少总是有效的。我可能会回去使用它。

标签: clojure


【解决方案1】:

1) 我希望让序列变得懒惰无济于事,因为 print 会在打印之前评估实现它。而是尝试doseq(map print my-seq) 以更小的块打印。

2) 是的,将它包装在 vec 中会给你想要的东西:) 虽然用 into 包装你的 reduce 会一直保持它是一个向量。即:(reduce into [] [[1] [2] [3]] ) --> [1 2 3]

  (into out-log (sorted-map cmp-val (vector lnam fnam)))))

【讨论】:

  • 谢谢。你是对的。 println 实现了一个惰性序列到内存中(因为我发布了临时代码)并且我得到了相同的堆栈溢出错误。我最初的目标是将输出保留为地图,然后将其打印出来,但我会没有地图,因为无论如何函数的输出都会写入文件。
  • into 也做地图 :)(into 和 update-in 是我的“本周功能”)
猜你喜欢
  • 1970-01-01
  • 2012-08-25
  • 2011-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多