Home > Software engineering >  "Left Join" like production of two collections in for-yield
"Left Join" like production of two collections in for-yield

Time:09-21

I have two collections - spells and charms.
charms might be empty

I need to do Magic of the combinations of spells and charms and if charms is empty I need Magic of spells alone

For non-empty charms this works:

def hocusPocus(spells: Seq[String], charms: Seq[String]): Seq[Magic] = {
  for {
    spell <- spells
    charm <- charms
  } yield {
    new Magic(spell, Some(charm))
  }
}

This snippet is simple and clean, but for empty charms it makes no Magic

Is there any possibility to do some Magic from spells only in such a clear way, if one is out of charms?

CodePudding user response:

This is one of those cases where it is easier to use flatMap map directly instead of using for (IMHO)
Also, it is a good use case to prefer a concrete collection like List over Seq

def hocusPocus(spells: List[String], charms: List[String]): List[Magic] =
  spells.flatMap { spell =>
    Magic(spell, None) :: charms.map(charm => Magic(spell, Some(charm)))
  }

Now, if you only need the Magic of spells alone if and only if charms is empty, you can do this:

def hocusPocus(spells: Seq[String], charms: Seq[String]): Seq[Magic] =
  if (charms.isEmpty)
    spells.map(spell => Magic(spell, None))
  else
    spells.flatMap { spell =>
      charms.map { charm =>
        Magic(spell, Some(charm))
      }
    }

CodePudding user response:

If it's possible to change type of Magic.charm to java.io.Serializable

you can write:

def hocusPocus(spells: Seq[String], charms: Seq[String]): Seq[Magic] = {
    for {
      spell <- spells
      charm <- if (charms.isEmpty) List(Option.empty) else charms
    } yield {
      new Magic(spell, charm)
    }
  }
  • Related