【问题标题】:Get differences between members of a list获取列表成员之间的差异
【发布时间】:2013-11-12 15:27:51
【问题描述】:

我有一个值列表,并希望将其简化为连续成员之间的差异列表。有没有比我想出的更好的方法(简单的例子)?

val l1 = List(1,2,3,4,5,6)

val diffs = (l1 zip l1.drop(1)).map{case (x,y) => y - x}.sum

【问题讨论】:

  • List(a1, a2, a3, ... aN) => (a1 - a2) + (a2 - a3) + ... + (aN-1 - aN) == a1 - aN => diffs == l1.head - l2.last.

标签: scala collections


【解决方案1】:

我确定我以前回答过一个非常相似的问题,但我找不到。不管怎样,试试zipped,因为它更高效并且语法更好:

(l1 drop 1, l1).zipped.map(_-_).sum

【讨论】:

  • 不错,将删除的版本首先放入元组中
  • 整洁。在我尝试过的临时基准测试中,如下所示的滑动解决方案似乎要慢得多。
【解决方案2】:

我喜欢在这个用例中使用sliding

val l1 = List(1,2,3,4,5,6)
val diffs = l1.sliding(2).map{case List(x, y) => x - y}.sum

试试here

【讨论】:

    【解决方案3】:

    你可以使用滑动

    l1.sliding(2).map { case Seq(a, b) => b - a } .sum
    

    但这并没有更短。另外,如果你有一个列表,你可以使用l1.tail 而不是l1.drop(1)

    我曾经写过如下扩展方法:

    import collection.generic.CanBuildFrom
    
    implicit final class RichIterableLike[A, CC[~] <: Iterable[~]](val it: CC[A])
      extends AnyVal {
      def mapPairs[B, To](fun: (A,A)=>B)(implicit cbf: CanBuildFrom[CC[A], B, To]): To = {
        val b     = cbf(it)
        val iter  = it.iterator
        if (iter.hasNext) {
          var pred = iter.next()
          while (iter.hasNext) {
            val succ = iter.next()
            b += fun(pred, succ)
            pred = succ
          }
        }
        b.result()
      }
    }
    

    这样:

    l1.mapPairs(-_+_).sum
    

    【讨论】:

    • 使用drop(1) 而不是tail 是更好的选择,因为对于空序列是安全的。例如,Nil.tail 引发异常,但 Nil.drop(1) 返回 Nil
    猜你喜欢
    • 2011-03-28
    • 2014-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    • 1970-01-01
    相关资源
    最近更新 更多