Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 将列表提取到多个不同的列表_Scala_List - Fatal编程技术网

Scala 将列表提取到多个不同的列表

Scala 将列表提取到多个不同的列表,scala,list,Scala,List,如何将Scala列表提取到Scala中具有多个不同列表的列表 从 到 下面是一种(效率相当低)的方法:按值分组,按组大小对结果排序,然后使用第一个组作为原始组每次索引扫描的基础,以构建不同的列表: scala> val l = List(1,2,6,3,5,4,4,3,4,1) l: List[Int] = List(1, 2, 6, 3, 5, 4, 4, 3, 4, 1) scala> val groups = l.groupBy(identity).values.toList

如何将Scala列表提取到Scala中具有多个不同列表的列表

下面是一种(效率相当低)的方法:按值分组,按组大小对结果排序,然后使用第一个组作为原始组每次索引扫描的基础,以构建不同的列表:

scala> val l = List(1,2,6,3,5,4,4,3,4,1)
l: List[Int] = List(1, 2, 6, 3, 5, 4, 4, 3, 4, 1)

scala> val groups = l.groupBy(identity).values.toList.sortBy(- _.size)
groups: List[List[Int]] = List(List(4, 4, 4), List(1, 1), List(3, 3), List(5), List(6), List(2))

scala> groups.head.zipWithIndex.map { case (_, i) => groups.flatMap(_.drop(i).headOption) }
res9: List[List[Int]] = List(List(4, 1, 3, 5, 6, 2), List(4, 1, 3), List(4))

这里还有另一个选项-扫描输入N次,其中N是单个值的最大重复次数:

// this function splits input list into two: 
// all duplicate values, and the longest list of unique values
def collectDistinct[A](l: List[A]): (List[A], List[A]) = l.foldLeft((List[A](), List[A]())) {
  case ((remaining, distinct), candidate) if distinct.contains(candidate) => (candidate :: remaining, distinct)
  case ((remaining, distinct), candidate) => (remaining, candidate :: distinct)
}

// this recursive function takes a list of "remaining" values,
// and a list of distinct groups, and adds distinct groups to the list
// until "remaining" is empty
@tailrec
def distinctGroups[A](remaining: List[A], groups: List[List[A]]): List[List[A]] = remaining match {
  case Nil => groups
  case _ => collectDistinct(remaining) match {
    case (next, group) => distinctGroups(next, group :: groups)
  }
}

// all second function with our input and an empty list of groups to begin with:
val result = distinctGroups(l, List())

在@TzachZohar的第一个答案中,分组后的另一种方法是从每个列表中提取一个元素,直到所有列表都为空:

val groups = l.groupBy(identity).values

Iterator
  // continue removing the first element from every sublist, and discard empty tails
  .iterate(groups)(_ collect { case _ :: (rest @ (_ :: _)) => rest } )
  // stop when all sublists become empty and are removed
  .takeWhile(_.nonEmpty)
  // build and sort result lists 
  .map(_.map(_.head).toList.sorted)
  .toList

考虑这种方法:

trait Proc {
  def process(v:Int): Proc
}
case object Empty extends Proc {
  override def process(v:Int) = Processor(v, Map(0 -> List(v)), 0)
}
case class Processor(prev:Int, map:Map[Int, List[Int]], lastTarget:Int) extends Proc {
  override def process(v:Int) = {
    val target = if (prev==v) lastTarget+1 else 0
    Processor(v, map + (target -> (v::map.getOrElse(target, Nil))), target)
  }
}

list.sorted.foldLeft[Proc](Empty) {
  case (acc, item) => acc.process(item)
}
这里我们有一个简单的状态机。我们迭代初始状态为“空”的排序列表。一旦“空”处理项目,它将生成下一个状态“处理器”。 处理器在“prev”中具有以前的值,并且已分组项目的累积映射。它还有lastTarget—上次写入发生的列表的索引。 “Processor”所做的唯一一件事是计算当前处理项的目标:如果它与上一个相同,它将采用下一个索引,否则它将从索引0开始

val groups = l.groupBy(identity).values

Iterator
  // continue removing the first element from every sublist, and discard empty tails
  .iterate(groups)(_ collect { case _ :: (rest @ (_ :: _)) => rest } )
  // stop when all sublists become empty and are removed
  .takeWhile(_.nonEmpty)
  // build and sort result lists 
  .map(_.map(_.head).toList.sorted)
  .toList
trait Proc {
  def process(v:Int): Proc
}
case object Empty extends Proc {
  override def process(v:Int) = Processor(v, Map(0 -> List(v)), 0)
}
case class Processor(prev:Int, map:Map[Int, List[Int]], lastTarget:Int) extends Proc {
  override def process(v:Int) = {
    val target = if (prev==v) lastTarget+1 else 0
    Processor(v, map + (target -> (v::map.getOrElse(target, Nil))), target)
  }
}

list.sorted.foldLeft[Proc](Empty) {
  case (acc, item) => acc.process(item)
}