List 按Scala中的给定事件对列表进行分组

List 按Scala中的给定事件对列表进行分组,list,scala,unzip,sliding,List,Scala,Unzip,Sliding,我有一个字符串列表,我试图按顺序将其拆分为单独的列表,将第四个出现的字符串分组,即此列表: val data = List("1", "2", "3", "4", "5", "6", "7", "8") 应分组为 val list1 = List("1", "5") val list2 = List("2", "6") val list3 = List("3", "7") val list4 = List("4", "8") 我不确定我是否试图将其过度复杂化,但我唯一能想到的方法是首先使用

我有一个字符串列表,我试图按顺序将其拆分为单独的列表,将第四个出现的字符串分组,即此列表:

val data = List("1", "2", "3", "4", "5", "6", "7", "8") 
应分组为

val list1 = List("1", "5")
val list2 = List("2", "6")
val list3 = List("3", "7")
val list4 = List("4", "8")
我不确定我是否试图将其过度复杂化,但我唯一能想到的方法是首先使用
滑动
对元素进行分组,例如:

data.sliding(4,4).toList 
导致

List(List(1, 2, 3, 4), List(5, 6, 7, 8))
然后实现我自己的
解压
方法,将上述内容分组为我想要的输出


有没有更简单的方法可以让我知道

您可以使用列表中的
.transpose
。滑动
生成:

scala> val data = List("1", "2", "3", "4", "5", "6", "7", "8") 
data: List[String] = List(1, 2, 3, 4, 5, 6, 7, 8)

scala> data.sliding(4, 4).toList
res1: List[List[String]] = List(List(1, 2, 3, 4), List(5, 6, 7, 8))

scala> data.sliding(4, 4).toList.transpose
res2: List[List[String]] = List(List(1, 5), List(2, 6), List(3, 7), List(4, 8))

您可以使用列表中的
.transpose
。滑动
生成:

scala> val data = List("1", "2", "3", "4", "5", "6", "7", "8") 
data: List[String] = List(1, 2, 3, 4, 5, 6, 7, 8)

scala> data.sliding(4, 4).toList
res1: List[List[String]] = List(List(1, 2, 3, 4), List(5, 6, 7, 8))

scala> data.sliding(4, 4).toList.transpose
res2: List[List[String]] = List(List(1, 5), List(2, 6), List(3, 7), List(4, 8))

zip
滑动后

scala> val data = List("1", "2", "3", "4", "5", "6", "7", "8")
data: List[String] = List("1", "2", "3", "4", "5", "6", "7", "8")

scala> val result = data.sliding(4, 4).toList
result: List[List[String]] = List(List("1", "2", "3", "4"), List("5", "6", "7", "8"))

scala> result.transpose
res7: List[(String, String)] = List(("1", "5"), ("2", "6"), ("3", "7"), ("4", "8"))

zip
滑动后

scala> val data = List("1", "2", "3", "4", "5", "6", "7", "8")
data: List[String] = List("1", "2", "3", "4", "5", "6", "7", "8")

scala> val result = data.sliding(4, 4).toList
result: List[List[String]] = List(List("1", "2", "3", "4"), List("5", "6", "7", "8"))

scala> result.transpose
res7: List[(String, String)] = List(("1", "5"), ("2", "6"), ("3", "7"), ("4", "8"))

如果元组可以作为输出,那么它相当整洁:

 val tuples = data zip data.drop(4)
 //> tuples  : List[(String, String)] = List((1,5), (2,6), (3,7), (4,8))
将它们转换为
列表

tuples.map{case(a,b) => List(a, b)} 
//> List[List[String]] = List(List(1, 5), List(2, 6), List(3, 7), List(4, 8))
编辑:显示有关仅使用8的注释不正确

 def pairs[A](xs:List[A], n:Int) =
 (xs zip xs.drop(n)).map{case(a,b) => List(a, b)}

pairs(List("1","2", "3", "4", "5", "6", "7", "8"), 4)
// List(List(1, 5), List(2, 6), List(3, 7), List(4, 8))
pairs(List("1","2", "3", "4", "5", "6", "7", "8", "9"), 4)
// List(List(1, 5), List(2, 6), List(3, 7), List(4, 8), List(5, 9))

pairs(List("1","2", "3", "4", "5", "6", "7", "8", "9", "10"), 4)
// List(List(1, 5), List(2, 6), List(3, 7), List(4, 8), List(5, 9), List(6, 10))
pairs(List("1","2", "3", "4"), 4)
// List()
pairs(List("1","2", "3"), 4)
// List()

如果元组可以作为输出,那么它相当整洁:

 val tuples = data zip data.drop(4)
 //> tuples  : List[(String, String)] = List((1,5), (2,6), (3,7), (4,8))
将它们转换为
列表

tuples.map{case(a,b) => List(a, b)} 
//> List[List[String]] = List(List(1, 5), List(2, 6), List(3, 7), List(4, 8))
编辑:显示有关仅使用8的注释不正确

 def pairs[A](xs:List[A], n:Int) =
 (xs zip xs.drop(n)).map{case(a,b) => List(a, b)}

pairs(List("1","2", "3", "4", "5", "6", "7", "8"), 4)
// List(List(1, 5), List(2, 6), List(3, 7), List(4, 8))
pairs(List("1","2", "3", "4", "5", "6", "7", "8", "9"), 4)
// List(List(1, 5), List(2, 6), List(3, 7), List(4, 8), List(5, 9))

pairs(List("1","2", "3", "4", "5", "6", "7", "8", "9", "10"), 4)
// List(List(1, 5), List(2, 6), List(3, 7), List(4, 8), List(5, 9), List(6, 10))
pairs(List("1","2", "3", "4"), 4)
// List()
pairs(List("1","2", "3"), 4)
// List()

适用于每个列表长度的版本:

def groupNth[A](n: Int, list: List[A]): List[List[A]] = {
  val (firstN, rest) = list.splitAt(n)
  val groupedRest = if (rest.nonEmpty) groupNth(n, rest) else Nil
  // null.asInstanceOf[A] is of course cheating, but the value is never used
  firstN.zipAll(groupedRest, null.asInstanceOf[A], Nil).map {
    case (h, t) => h :: t
  }
}


println(groupNth(4, Nil))
// List()
println(groupNth(4, List(1, 2, 3)))
// List(List(1), List(2), List(3))
println(groupNth(4, List(1, 2, 3, 4, 5, 6, 7, 8)))
// List(List(1, 5), List(2, 6), List(3, 7), List(4, 8))
println(groupNth(4, List(1, 2, 3, 4, 5, 6, 7, 8, 9)))
// List(List(1, 5, 9), List(2, 6), List(3, 7), List(4, 8))
println(groupNth(4, List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)))
// List(List(1, 5, 9), List(2, 6, 10), List(3, 7, 11), List(4, 8, 12))

适用于每个列表长度的版本:

def groupNth[A](n: Int, list: List[A]): List[List[A]] = {
  val (firstN, rest) = list.splitAt(n)
  val groupedRest = if (rest.nonEmpty) groupNth(n, rest) else Nil
  // null.asInstanceOf[A] is of course cheating, but the value is never used
  firstN.zipAll(groupedRest, null.asInstanceOf[A], Nil).map {
    case (h, t) => h :: t
  }
}


println(groupNth(4, Nil))
// List()
println(groupNth(4, List(1, 2, 3)))
// List(List(1), List(2), List(3))
println(groupNth(4, List(1, 2, 3, 4, 5, 6, 7, 8)))
// List(List(1, 5), List(2, 6), List(3, 7), List(4, 8))
println(groupNth(4, List(1, 2, 3, 4, 5, 6, 7, 8, 9)))
// List(List(1, 5, 9), List(2, 6), List(3, 7), List(4, 8))
println(groupNth(4, List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)))
// List(List(1, 5, 9), List(2, 6, 10), List(3, 7, 11), List(4, 8, 12))

这只在列表正好有8个元素的情况下才有效。这只在列表正好有8个元素的情况下才有效。这个答案还要求
data
正好有8个元素。我不知道你为什么这么说,因为这根本不是真的。如果你有例如
data=(1到12)。toList
你将返回
list(list(1,5),list(2,6),list(3,7),列表(4,8),列表(5,9),…)
;它不是像问题中那样“拆分成单独的列表”,因为您的结果是相交的。如果
data=(1到4).toList
,则返回一个空列表。问题中未指定长度超过8的列表的行为。或少于5个。你有一个解释,我认为这是不可能的,因为OP是如何解决它的
滑动(4,4)
。我认为我的答案更可能是正确的——我们将看到OP所说的。好吧,对于任何可以被4整除的长度,公认的答案都与我的答案一致(在其他情况下会抛出一个例外)。这个答案也要求
数据
正好有8个元素。我不知道你为什么这么说,因为这根本不是真的。如果你有例如
数据=(1到12)。toList
你将返回
列表(列表(1,5),列表(2,6),列表(3,7),列表(4,8),列表(5,9),…)
;它不是像问题中那样“拆分成单独的列表”,因为您的结果是相交的。如果
data=(1到4).toList
,则返回一个空列表。问题中未指定长度超过8的列表的行为。或少于5个。你有一个解释,我认为这是不可能的,因为OP是如何解决它的
滑动(4,4)
。我认为我的答案更可能是正确的——我们将看到OP所说的。好吧,对于任何可以被4整除的长度,公认的答案都与我的答案一致(在其他情况下会抛出一个例外)。它只适用于长度为8的列表。如果您能够确认长度超过8个元素的列表的预期行为,那将是非常棒的……如果您能够确认长度超过8个元素的列表的预期行为,那将是非常棒的。。。。