将多个连续的条目中的Scala /火花

我有如图逗号分隔的数字数组:将多个连续的条目中的Scala /火花

一个:{108,109,110,112,114,115,116,118}

我所需要的输出是这样的:

一个:{108-110,112,114-116,118}

我试图将连续的数字与之间的“ - ”进行分组。 例如,108,109,110是连续数字,所以我得到108-110。 112是单独的条目; 114,115,116再次代表一个序列,所以我得到114-116。 118是分开的,如此对待。

我在Spark中这样做。我写以下代码:

import scala.collection.mutable.ArrayBuffer 

def Sample(x:String):ArrayBuffer[String]={

val x1 = x.split(",")

var a:Int = 0

var present=""

var next:Int = 0

var yrTemp = ""

var yrAr= ArrayBuffer[String]()

var che:Int = 0

var storeV = ""

var p:Int = 0

var q:Int = 0

var count:Int = 1

while(a < x1.length)

{

yrTemp = x1(a)

if(x1.length == 1)

{

yrAr+=x1(a)

}

else

if(a < x1.length - 1)

{

present = x1(a)

if(che == 0)

{

storeV = present

}

p = x1(a).toInt

q = x1(a+1).toInt

if(p == q)

{

yrTemp = yrTemp

che = 1

}

else

if(p != q)

{

yrTemp = storeV + "-" + present

che = 0

yrAr+=yrTemp

}

}

else

if(a == x1.length-1)

{

present = x1(a)

yrTemp = present

che = 0

yrAr+=yrTemp

}

a = a+1

}

yrAr

}

val SampleUDF = udf(Sample(_:String))

我正在输出如下:

一个:{108-108,109-109,110-110,112,114-114,115- 115,116-116,118}

我无法弄清楚我哪里出错了。你能帮我解决这个问题吗? TIA。

回答:

这里的另一种方式:

def rangeToString(a: Int, b: Int) = if (a == b) s"$a" else s"$a-$b" 

def reduce(xs: Seq[Int], min: Int, max: Int, ranges: Seq[String]): Seq[String] = xs match {

case y +: ys if (y - max <= 1) => reduce(ys, min, y, ranges)

case y +: ys => reduce(ys, y, y, ranges :+ rangeToString(min, max))

case Seq() => ranges :+ rangeToString(min, max)

}

def output(xs: Array[Int]) = reduce(xs, xs.head, xs.head, Vector())//.toArray

你可以测试:

println(output(Array(108,109,110,112,114,115,116,118))) 

// Vector(108-110, 112, 114-116, 118)

基本上这是一个尾递归函数 - 即你把你的“变量”作为输入,然后调用本身在每个循环更新的“变量”。所以这里xs是你的数组,minmax是用来跟踪到目前为止最低和最高数字的整数,而ranges是当需要时被添加到的字符串的输出序列。

的第一图案(y是第一要素,并ys是该序列的其余部分 - 因为这是怎么+:提取的作品),如果有至少一个元素的匹配(ys可以是一个空列表),它遵循从之前的最大值开始。

第二个是如果它不继续,并且需要重置最小值并将完成的范围添加到输出。

第三种情况是我们已经到了输入的结尾并输出结果,而不是再次调用循环。

互联网业力指向任何人谁可以计算出如何消除重复ranges :+ rangeToString(min, max)

回答:

这里是一个解决方案:

def combineConsecutive(s: String): Seq[String] = { 

val ints: List[Int] = s.split(',').map(_.toInt).toList.reverse

ints

.drop(1)

.foldLeft(List(List(ints.head)))((acc, e) => if ((acc.head.head - e) <= 1)

(e :: acc.head) :: acc.tail

else

List(e) :: acc)

.map(group => if (group.size > 1) group.min + "-" + group.max else group.head.toString)

}

val in = "108,109,110,112,114,115,116,118"

val result = combineConsecutive(in)

println(result) // List(108-110, 112, 114-116, 118)

}

该解决方案部分使用代码来自这个问题:Grouping list items by comparing them with their neighbors

以上是 将多个连续的条目中的Scala /火花 的全部内容, 来源链接: utcz.com/qa/258005.html

回到顶部