Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.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 是否有与sortWith函数类似的本机分组函数?_Scala - Fatal编程技术网

Scala 是否有与sortWith函数类似的本机分组函数?

Scala 是否有与sortWith函数类似的本机分组函数?,scala,Scala,有一些库(如Spark和其他Scala扩展)具有可用的“groupWith”函数。此函数允许您将元素与集合的其余部分进行比较,然后使用一个或多个谓词对其进行分组。Scala中似乎没有任何本机功能,但它们确实有sortWith函数,该函数的行为类似,但只是对项目进行排序,而不是对项目进行分组。如果解释不充分,这里有一个小代码示例,可以显示我正在尝试做的事情: val list = List(1,2,3,4,5,5) val groupedList = list.groupWith{ (e,c) =

有一些库(如Spark和其他Scala扩展)具有可用的“groupWith”函数。此函数允许您将元素与集合的其余部分进行比较,然后使用一个或多个谓词对其进行分组。Scala中似乎没有任何本机功能,但它们确实有sortWith函数,该函数的行为类似,但只是对项目进行排序,而不是对项目进行分组。如果解释不充分,这里有一个小代码示例,可以显示我正在尝试做的事情:

val list = List(1,2,3,4,5,5)
val groupedList = list.groupWith{ (e,c) =>
    e == c
}
这是一个非常简单的例子,我想做更复杂的比较,比如

e + 1 == c
所以问题是,是否有任何本机Scala函数可以做到这一点?有什么建议或解决办法吗

更新: 从给出的简单示例来看,似乎不太清楚我想做什么,这里有一个更好的示例: 假设我有一个case类和这些对象的列表:

case class Item(num: Int, color: String)
val list = List(new Item(13, "red"), new Item(14,"red"), new Item(15, "blue"), new Item(16, "red"))

list.groupWith{ (e,c) =>
    (e.num -1 == c.num || e.num + 1 == c.num ) && e.color == c.color        
}
这应该会返回这样的结果:

res8: List[List[Item]] = List(List(Item(13,red), Item(14,red)), List(Item(15,blue)), List(Item(16,red)))

不确定这是否是您想要的(请查看我对您的问题的评论),但有一种方法定义为
groupBy
,其中
List
继承(而不仅仅是List)。您将获得:

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

scala> list.groupBy( el => el )
res0: scala.collection.immutable.Map[Int,List[Int]] = Map(5 -> List(5, 5), 1 -> List(1), 2 -> List(2), 3 -> List(3), 4 -> List(4))

scala> list.groupBy( el => el + 1 )
res1: scala.collection.immutable.Map[Int,List[Int]] = Map(5 -> List(4), 6 -> List(5, 5), 2 -> List(1), 3 -> List(2), 4 -> List(3))
基本上,您需要提供从值到键的鉴别器功能,您将得到
Map[key,List[value]


这就是您想要的吗?

下面是一个实现:

// Takes the list as a parameter, can use pimp-my-library if you want
def groupWith[A](xs: List[A], f: (A, A) => Boolean) = {
  // helper function to add "e" to any list with a member that matches the predicate
  // otherwise add it to a list of its own
  def addtoGroup(gs: List[List[A]], e: A): List[List[A]] = {
    val (before, after) = gs.span(_.exists(!f(_, e)))
    if (after.isEmpty)
      List(e) :: gs
    else
      before ::: (e :: after.head) :: after.tail
  }
  // now a simple foldLeft adding each element to the appropriate list
  xs.foldLeft(Nil: List[List[A]])(addtoGroup)
} 

groupWith(list, { (e: Item, c: Item) =>
                    (e.num - 1 == c.num || e.num + 1 == c.num) && e.color == c.color})

//| res0: List[List[groups.groups.Item]] =
//         List(List(Item(16,red)),
//              List(Item(15 ,blue)), 
//              List(Item(14,red), Item(13,red)))

你能告诉我们,那些不熟悉w/Spark groupWith的人,你在这两种情况下的
groupedList
结果吗?我缺少
groupWith
的语义。你只想按顺序分组对,即(1,3,2,3)和(e,e+1),它是返回(1,2)、(2,3)、(2,3)还是仅仅返回(2,3)?因此,如果与组中的任何现有成员相比,事物通过谓词,那么它们最终会进入a组?这显然是O(N^2),可以吗?是的,这比生产代码问题更令人好奇,如果你看看本机的sortWith函数,我会想象它有同样的复杂性。不完全是这样,我知道groupBy函数,但它只允许你与元素本身进行比较,所以基于,比如,数字接近度的分组操作是不可能的这(我认为)。请参阅我的更新以更清楚地了解我在寻找什么。这种方法完全符合函数需要做什么的描述,但我正在寻找Scala固有的东西(即我不需要自己编写的东西).好吧,你不需要自己写。我是为你写的:)据我所知,标准库中没有任何东西能完全满足你的需要。没错,我想这本身就回答了我的问题,这是我将要找到的一个很好的答案,谢谢!