2017-05-30 210 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

谢谢你的回应。有时候一个可变的状态有很长的路要走...... –