-2

I have a List[String]. I want to group it by a given equivalence relation:

def f(x: String, y: String): Boolean = {
  if (x == "" || y == "") {
    false
  } else {
    x == y
  }
}

I have tried method groupBy, but I cannot achieve empty strings to be in separate groups.

I would prefer the answer for any equivalence relation f(x: String, y: String): Boolean, not just this one.

EDIT: I have not specified, but the input type is really List[String], not List[(String, String)], f is a binary relation, that's why it has 2 String inputs, and expected return type is List[List[String]]

EDIT: As @andrey-tyukin mentioned, f is not an equivalence relation, so requesting "answer for any equivalence relation" is nonsense.

EDIT: An example:

Input: List("a", "a", "b", "", "")
Output: List(List("a", "a"), List("b"), List(""), List(""))
  • "a" == "a", that's why they go in the same group
  • Although "" == "", but f would result in false, so they are not in the same group
mirelon
  • 4,896
  • 6
  • 40
  • 70
  • Why `f` takes two parameters? Do you have a `List[(String, String)]`? BTW I think `partition` can help you in this task... – gianluca aguzzi Aug 12 '21 at 07:20
  • 5
    It's not at all clear what you're trying to achieve. Can you give an example input and the result groups? – jwvh Aug 12 '21 at 07:36
  • 4
    That's not an equivalence relation, because it's not reflexive: `f("", "")` is false. – Andrey Tyukin Aug 12 '21 at 09:25
  • 1
    So input `List("a","a","b","a")` would result with 3 groups: `("a","a")`, `("b")`, and `("a")`. Is that correct? – jwvh Aug 13 '21 at 18:31

3 Answers3

1

How about this:

val strs = List("a", "", "b", "c", "", "a", "a", "c")
val grps = strs.sorted.foldLeft(Nil: List[List[String]]){ 
  case (h::tl, s) if h.head == s && s.nonEmpty => (s::h) :: tl 
  case (r, s) => List(s) :: r 
}
esse
  • 1,415
  • 5
  • 10
0

groupBy partitioning by value, not by relation.

You need a function that will map your any equivalent object to same value.

talex
  • 17,973
  • 3
  • 29
  • 66
0

I'm not sure what you want, it seems like your data is List[(String, String)]?

If so, you can try this

def f(x: String, y: String): Boolean = {
  if (x == "" || y == "") {
    false
  } else {
    x == y
  }
}

val xs = List(("", ""), ("", "1"), ("1", "1"), ("1", "2"))

val res = xs.groupBy((f _).tupled)
println(res)
// Map(false -> List((,), (,1), (1,2)), true -> List((1,1)))
counter2015
  • 869
  • 7
  • 18