Scala 如何将列表元素与下一个元素进行比较,以生成此元素?

Scala 如何将列表元素与下一个元素进行比较,以生成此元素?,scala,Scala,正如我在标题中提到的,如何比较索引N的元素和索引N+1的元素,如果所比较的元素完全相同,则只产生一次元素。 我知道我可以使用toSet来获取一组唯一的元素,但这对我没有帮助,因为我的列表可以包含重复的元素,但重复的元素不能是列表中的下一个元素 val ll = List(1, 2, 3, 6, 3, 7, 5, 5, 6, 3) // Desired output: List(1, 2, 3, 6, 3, 7, 5, 6, 3) 我使用zipWithIndex.collect得到了一个“近似工

正如我在标题中提到的,如何比较索引N的元素和索引N+1的元素,如果所比较的元素完全相同,则只产生一次元素。 我知道我可以使用toSet来获取一组唯一的元素,但这对我没有帮助,因为我的列表可以包含重复的元素,但重复的元素不能是列表中的下一个元素

val ll = List(1, 2, 3, 6, 3, 7, 5, 5, 6, 3)
// Desired output: List(1, 2, 3, 6, 3, 7, 5, 6, 3)
我使用zipWithIndex.collect得到了一个“近似工作的解决方案”,但当我在其中进行比较时,索引超出了边界。如果我能在里面使用两个条件,我就可以实现这一点,首先检查最大索引为index=(list.size-1),然后我可以比较list(index)!=列表(索引+1)然后是收益列表(索引)

我的尝试没有成功(因为边界外),是:

如果我可以使用一个以上的条件来限制索引,这可以工作,但在两个条件下不起作用:

times.zipWithIndex.collect
{
    case (element, index)
        if (index < times.size)
            if (times(index) != times(index+1)) => times(index)
}
times.zipWithIndex.collect
{
案例(元素、索引)
如果(索引<倍大小)
如果(次数(索引)!=次数(索引+1))=>次数(索引)
}

我欣赏任何一种选择。

您可以使用压缩列表本身,删除第一个元素,以便比较索引N和N+1处的元素。您只需要追加最后一个元素(可能需要使用
ListBuffer
,因为追加最后一个元素需要复制列表)



您可以将列表本身压缩,删除第一个元素,以便将索引N处的元素与N+1处的元素进行比较。您只需要追加最后一个元素(可能需要使用
ListBuffer
,因为追加最后一个元素需要复制列表)


怎么样

ll.foldLeft(List[Int]())((acc, x) => acc match {case Nil => List(x) case y => if (y.last == x) y else y :+ x})
怎么样

ll.foldLeft(List[Int]())((acc, x) => acc match {case Nil => List(x) case y => if (y.last == x) y else y :+ x})

下面是我使用滑动功能的备选方案:

val ll = List(1, 2, 3, 6, 3, 7, 5, 5, 6, 3)
ll.sliding(2)
    .filter( t => t.length > 1 && t(0) != t(1) )
    .map( t => t(0) )
    .toList :+ ll.last

下面是我使用滑动功能的备选方案:

val ll = List(1, 2, 3, 6, 3, 7, 5, 5, 6, 3)
ll.sliding(2)
    .filter( t => t.length > 1 && t(0) != t(1) )
    .map( t => t(0) )
    .toList :+ ll.last

这将输出一个“畸形”结果:Vector(L,i,s,t):,L,i,s,t,(,1,,,2,,,3,,,6,,,3,,,7,,,5,,,5,,,6,,,6,,,3,,,3;Size:10)@LXSoft我已经在你的输入上测试过了,得到了预期的输出。val L:List[Int]=List(1,2,3,6,3,7,5,6)println(“List:+L.zip(L.drop(1))。带有过滤器(t=>t.=u.=1):+L.last+“Size:+L.zip(times.drop(1)).withFilter(t=>t.\u 1!=t.\u 2.map(.\u 1).Size)结果与第一条注释相同。@LXSoft因为涉及到字符串连接。在第一个表达式周围添加括号:
println(“List:”+(L.zip(L.drop(1)).withFilter(t=>t.\u 1!=t.\u 2).map(\u 1):+L.last)+“Size:”+L.zip(L.drop(1)).withFilter(t=>t.\u 1!=t.\u 2).map(\u 1).Size)
这将输出一个“畸形”结果,如:Vector(L,i,s,t,t,:,,,L,i,s,t,t,(,1,,,2,,,3,,,6,,,3,,,7,,,5,,,6,,,3;大小:10)@LXSoft我已经对你的输入进行了测试,我得到了预期的输出。val L:List[Int]=List(1,2,3,3,7,5,5,6,3)println(“List:+L.zip(L.drop(1))。带过滤器(t=>t.。。。\u 1!=t.。\u 2)。map(。\u 1:+L.last+“Size:+L.zip(times.drop(1.drop)(t))。)=t.)。\map:+t.)(.u.1).size)结果与第一条注释中的结果相同。@LXSoft因为涉及字符串连接。在第一个表达式周围添加括号:
println(“List:”+(L.zip(L.drop(1))。withFilter(t=>t.。\u 1!=t.\u 2)。map(\u.1):+L.last)+“size:+L.zip(L.drop(1))。with filter(t=>t.。\u 1!=t.\u 2.map(\u.size)
我一直很困惑,为什么Scala的集合库没有这种分组功能。在Haskell中,你可以把它写成
map head$group ll
@ChrisMartin你的意思是
map head$group ll
是完整的代码,会给出所需的输出吗?我很好奇…@bjfletcher是的:)重吊由
组完成,该组将
[1,2,3,6,3,7,5,5,6,3]
转换为
[1]、[2]、[3]、[6]、[3]、[7]、[5,5]、[6]、[3]]
@ChrisMartin Nice,确实非常好。我只是问了一个问题。我一直很困惑为什么Scala的集合库没有这种分组功能。在Haskell中,您可以将其写成
映射头$group ll
@ChrisMartin您的意思是
映射头$group ll
是完整的代码,并且会给出期望的输出?我很好奇…@bjfletcher是的:)沉重的提升是由
团队完成的,这将
[1,2,3,6,3,7,5,5,6,3]
变成
[1]、[2]、[3]、[6]、[3]、[7]、[5,5]、[6]、[3]
@ChrisMartin Nice,确实非常好。我刚才问了一个问题。
val ll = List(1, 2, 3, 6, 3, 7, 5, 5, 6, 3)
ll.sliding(2)
    .filter( t => t.length > 1 && t(0) != t(1) )
    .map( t => t(0) )
    .toList :+ ll.last