2016-02-29 92 views

回答

1

对我来说,最可读的,似乎使用zip,随着最后一个元素荏苒重复无限:

l.init zip Stream.continually(l.last) 

的缺点是l.last被重复计算,因此,如果您关心与大型列表的性能,你可能喜欢首先将其赋值给一个值:

val last = l.last 
l.init zip Stream.continually(last) 

,或者您可以使用from与零一步,以避免惰性计算:

l.init zip Stream.from(l.last, 0) 

类似的版本可使用map来完成,映射所有但tupled最后元件的最后一个 - 再次,l.last将在每次迭代进行评估,除非由可变取代:

l.init map ((_, l.last)) 

如果您更改输入以使重复元素优先(List(99,1,2,3)),则可以使用l.headl.tail而不是l.lastl.init,这更自然并且没有性能缺陷:

l.tail zip Stream.continually(l.head) 

或:

l.tail map ((_, l.head)) 
+0

Stream类似乎更容易。我不知道那堂课。 – Guille

+0

请注意'List#last'是一个部分函数:'scala> List()。last java.util.NoSuchElementException' –

4

也许不是最好的解决办法,但这里有云:

l map ((_, l.last)) init 

另一种疯狂的想法可能是:

l.init zip List.fill(l.length -1)(l.last) 
+0

'选择除了last' http://www.scala-lang.org/api/2.11所有元素.7/index.html#scala.collection.immutable.List @ init:Repr – mfirry

1

与此代码,你不需要担心列出一个元素或是空的。

val resultList:List[(Int,Int)] = List(1,2,3,99) match { 
    case Nil => Nil 
    case x :: Nil => //do what you have to do if there is only one element 
    case xs => xs.init zip Stream.continually(xs.last) //an infinit stream of the last element 
} 
+0

第二种情况是不必要的:第三种情况将返回空列表,因为对于一个元素列表,“xs.init”将为空。 – Suma

+0

这是对的,但也许他有一个要求如何处理这种情况。情况2是有逻辑而非技术原因的。 –

1

使用的理解,对于给定的名单xs

for (i <- xs.init; z = xs.last) yield (i,z) 

在一个有序集合,init提供所有,但最后的元素。

更新

,处理空列表,以及一个方法,

for (i <- xs.dropRight(1); z <- xs.takeRight(1)) yield (i,z) 
+0

我非常喜欢这个。使用'for'是一种很好的方式,可以在不需要使用多个语句的情况下为'last'引入一个变量。 – Suma