【问题标题】:Scala: How to sum all elements with the same index in a list of lists of different lengths?Scala:如何对不同长度列表中具有相同索引的所有元素求和?
【发布时间】:2019-09-28 16:03:09
【问题描述】:

我有一个整数列表。需要获取列中所有元素的总和列表,从右到左,如果列中的值不存在(一行比其他行短),则设为 0:

            ( 1,  7),
    ( 3,  4,  6,  0),
                  (),
( 9,  1,  6,  7,  2),
                 ...
---------------------
( 9,  4, 10, 14,  9)

我是用 Java(比如命令式语言)编写的:

    int[][] s = {
                 { 1, 7 },
           { 3, 4, 6, 0 },
                       {},
        { 9, 1, 6, 7, 2 }
    };
    
    int maxLen = 0;
    for (int[] x : s) {
      maxLen = Integer.max(maxLen, x.length);
    }
    
    int[] sum = new int[maxLen];
    for (int j = maxLen; j-- > 0; ) {
      for (int[] i : s) {
        int idxFromEnd = j - maxLen + i.length;
        sum[j] += idxFromEnd >= 0 ? i[idxFromEnd] : 0;
      }
    }

然后翻译成Scala:

  val s = List(
             List( 1, 7 ),
       List( 3, 4, 6, 0 ),
                   List(),
    List( 9, 1, 6, 7, 2 ),
  )

  val maxLen = s.view.map(_.length).max
  val sum =
    for (i <- 0 until maxLen)
    yield s.view.map(row => {
      val idxFromEnd = i - maxLen + row.length
      row.lift(idxFromEnd).getOrElse(0)
    }).sum

请你们建议一种用 Scala 编写它的惯用方式。尾递归也是可以接受的。

【问题讨论】:

    标签: scala-collections


    【解决方案1】:

    您可以使用groupByflatMap

    val s = List(
                 List( 1, 7 ),
                 List( 3, 4, 6, 0 ),
                 List(),
                 List( 9, 1, 6, 7, 2 ),
                )
    
    s.flatMap(_.zipWithIndex).groupBy{case (num, idx) => idx}
     .map{case (k, v) => v.map(_._1).sum}.toList
    
    

    【讨论】:

      【解决方案2】:

      zipAll 对于不同长度的列表很有用,所以这样的东西可以工作:

      s.reduce((a,b) => //-- combining elements of s...
        a.reverse //-- work from right to left
          .zipAll(b.reverse,0,0) //-- join at the hip - right to left
          .map ( i => i._1 + i._2 ) //-- adding the corresponding elements
      ).reverse //-- display in left to right order
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-21
        • 1970-01-01
        • 2013-08-18
        • 2018-06-15
        • 1970-01-01
        • 2018-08-09
        • 1970-01-01
        相关资源
        最近更新 更多