2017-05-30 66 views
0

給定一個Iterator[String]它是很容易創建CSV String使用mkString:定製mkString功能斯卡拉迭代

//Result: "1,2,3,4,5" 
Iterator("1","2","3","4","5").mkString(",") 

與mkString的問題是,它會消耗內存來保存整個結果字符串。

是否可以將變換應用於原始迭代器,該變換器提供與mkString相同的輸出,但不會將內存與整個結果綁定在一起?

val csvIter : Iterator[String] = doSomething(Iterator("1","2","3","4","5")) 

出於測試目的,下面的表達式應該返回true:

val originalIter : Iterator[String] = ??? 

originalIter.mkString(",") == doSomething(originalIter).reduceOption(_ + _).getOrElse("") 

預先感謝您的關懷和響應。

+0

'iterator.map(_ +「,」)'? – Dima

+0

@Dima這個解決方案在最後一個元素之後留下一個揮之不去的','。 mkString沒有這個缺陷... –

+0

你會允許'Iterator(「1」,「,2」,「,3」,...)'? –

回答

1

下面是處理所有其他之前的第一個元素涉及一個解決方案:

def mkString(it: Iterator[String]) = if (it.hasNext) 
    Iterator(it.next()) ++ it.map("," + _) 
else it 
+0

謝謝你的迴應。正是我在找什麼。 –

+0

請注意,之後您不應該重複使用'it',因爲它被視爲被map所消耗。 –

1

不知道是否對你很重要,但是這將交織分隔爲不同的元素:

def mkString(iter: Iterator[String], sep: String) = new Iterator[String] { 
    var nextIsSep = false 
    def hasNext: Boolean = iter.hasNext 
    def next(): String = { 
    val result = if (nextIsSep) sep else iter.next() 
    nextIsSep = !nextIsSep 
    result 
    } 
} 
+0

謝謝你的迴應。有時候一個可變的狀態有很長的路要走...... –