There are a few libraries such as Spark and other Scala extensions that have the \"groupWith\" function available. This function allows you to compare an element to the rest
Not sure if this what you want (check my comments to your question), but there is method groupBy
defined in GenTraversableLike which List
inherits (not only List). You will get:
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))
Basically you need to provide discriminator function from value to key and you will get Map[Key, List[Value]
.
Is this what you want?
Here's an implementation:
// 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)))