1

I am often in the situation of doing this type of filtering:

allPeople
  .filter(person => englishPeopleIds contains person.id)

and it would make my life easier and my code more readable if there was some sort of "belongsTo" function to do the following:

allPeople
  .filter(_.id belongsTo englishPeopleIds)

belongsTo function would have this kind of behaviour (but would be a method of the element):

def belongsTo[T](element: T, list: List[T]): Boolean = list contains element

Do you know if such function is already implemented in Scala?

MoutonGros
  • 21
  • 2
  • Related: https://stackoverflow.com/questions/26185989/scala-equivalent-of-pythons-in-operator-for-sets – user May 29 '20 at 12:52

2 Answers2

3

Perhaps define a right-associative operator on a sequential collections like so

implicit class ElementOf[A](l: Seq[A]) {
  def ∈: (a: A): Boolean = l contains a
}

using mathematical symbol element of ∈ which falls under Scala operator characters, and then call-site becomes

allPeople filter (_.id ∈: englishPeopleIds)

To make it work also for Set and Map as well try defining in terms of Iterable#exists like so

implicit class ElementOf[A](cc: Iterable[A]) {
  def ∈: (a: A): Boolean = cc exists (_ == a)
}
Mario Galic
  • 47,285
  • 6
  • 56
  • 98
1

No, but you could use an implicit class to do the same:

implicit class BelongsTo[T](private val t: T) extends AnyVal {
  def belongsTo(s: Seq[T]): Boolean = s.contains(t)
  def belongsTo(s: Set[T]): Boolean = s(t)
}

In Dotty, you can do this:

extension [T](t: T):
  def belongsTo(s: Seq[T]): Boolean = s.contains(t)
  def belongsTo(s: Set[T]): Boolean = s(t)

Honestly, though, it doesn't seem worth it.

user
  • 7,435
  • 3
  • 14
  • 44
  • 1
    Make the implicit class also an **AnyVal** to avoid the cost of instantiation. Also, it may be worth to make it work for any collection, not juts lists. – Luis Miguel Mejía Suárez May 29 '20 at 13:15
  • @LuisMiguelMejíaSuárez I tried to apply your suggestion, but it seems `contains` isn't present in Iterable and is implemented differently in Set, Seq, and Map? – user May 29 '20 at 13:31
  • 1
    Really? Dude, abstracting over collections is really weird. – Luis Miguel Mejía Suárez May 29 '20 at 13:40
  • 1
    @LuisMiguelMejíaSuárez Yeah, it inspired someone to make this question: https://stackoverflow.com/questions/1722726/is-the-scala-2-8-collections-library-a-case-of-the-longest-suicide-note-in-hist – user May 29 '20 at 13:41