代码之家  ›  专栏  ›  技术社区  ›  minerals

创建元素方向的差异在scala中为1的序列组?

  •  2
  • minerals  · 技术社区  · 6 年前

    我们有以下的数字序列:[19,23,24,31,126,127,155,159,160,161]。我们需要根据相邻值之间的差异对该序列进行分组,这样,如果组大小为>1,每组值的差异将等于1。

    在python中,我将编写如下内容:

    outliers = [19, 23, 24, 31, 126, 127, 155, 159, 160, 161]
    
    chains = [[i for i in list(map(itemgetter(1), g))]
               for _, g in itertools.groupby(enumerate(outliers),
                                             lambda x: x[0]-x[1])]
    
    # [[19], [23, 24], [31], [126, 127], [155], [159, 160, 161]]
    

    挺干净的。但是,如何在scala中做到这一点而不必返回到有条件的循环中呢?我一直在努力 zipWithIndex groupBy 方法到目前为止还没有用:(

    2 回复  |  直到 6 年前
        1
  •  2
  •   jwvh    6 年前

    你可以 fold 在整个序列中,在进行过程中构建结果。

    outliers.foldRight(List.empty[List[Int]]) {case (n, acc) =>
      if (acc.isEmpty) List(List(n))
      else if (acc(0)(0) == n+1) (n :: acc.head) :: acc.tail
      else List(n) :: acc
    }
    //res0: List[List[Int]] = List(List(19), List(23, 24), List(31), List(126, 127), List(155), List(159, 160, 161))
    
        2
  •  1
  •   Hayk Hakobyan    6 年前

    不确定递归是否可以与您的条件匹配,但它最后是O(N)。

    def rec(source: List[Int], temp: List[Int], acc: List[List[Int]]): List[List[Int]] = source match {
        case Nil => acc
        case x :: xs => {
            if (xs.nonEmpty && xs.head - x == 1) rec(xs, temp :+ x, acc)
            else rec(xs, List(), acc :+ (temp :+ x))
        }
    }
    val outliers = List(19, 23, 24, 31, 126, 127, 155, 159, 160, 161)
    rec(outliers, List[Int](), List[List[Int]]())