如果我有一个稀疏的数字列表:
int amount
我需要生成一个固定大小的字符串,用一个给定的字符替换'missing'数字,如下所示:
Vector(1,3,7,8,9)
我如何在Scala中执行此操作?
答案 0 :(得分:4)
好吧,我不确定整数的范围。所以我假设它们可能不适合char并使用字符串。试试这个:
val v = Vector(1,3,7,8,9)
val fixedStr = ( v.head to v.last )
.map( i => if (v.contains(i)) i.toString else "." )
.mkString
如果您只处理个位数,那么您可以将字符串更改为上面的字符。
- 编辑 -
好的,所以我无法帮助自己并解决稀疏矢量的问题,并希望将其更改为使用滑动功能。想知道坐在我的电脑上并不好,所以在这里分享:v.sliding(2)
.map( (seq) => if (seq.size == 2) seq else seq ++ seq ) //normalize window to size 2
.foldLeft( new StringBuilder )( (sb, seq) => //fold into stringbuilder
seq match { case Seq(a,b) => sb.append(a).append( "." * (b - a - 1) ) } )
.append( v.last )
.toString
答案 1 :(得分:2)
一种方法是使用sliding
和模式匹配:
def mkNiceString(v: Vector[Int]) = {
v.sliding(2).map{
case Seq(a) => ""
case Seq(a,b) =>
val gap = b-a;
a.toString + (if(gap>1) "." * (gap-1) else "")
}.mkString + v.last
}
在REPL中:
scala> mkNiceString(Vector(1,3,7,8,9,11))
res22: String = 1.3...789.11
答案 2 :(得分:1)
如果向量稀疏,这比检查第一个和最后一个数字之间的范围更有效。
def padVector(numbers: Vector[Int], placeHolder: String) = {
def inner(nums: Vector[Int], prevNumber: Int, acc: String) : String =
if (nums.length == 0) acc
else (nums.head - prevNumber) match {
// the difference is 1 -> no gap between this and previous number
case 1 => inner(nums.tail, nums.head, acc + nums.head)
// gap between numbers -> add placeholder x times
case x => inner(nums.tail, nums.head, acc + (placeHolder * (x-1)) + nums.head)
}
if (numbers.length == 0) ""
else inner(numbers.tail, numbers.head, numbers.head.toString)
}
输出:
scala> padVector(Vector(1,3,7,8,9), ".")
res4: String = 1.3...789