Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Cabbage Disrespect
Apr 24, 2009

ROBUST COMBAT
Leonard Riflepiss
Soiled Meat

KICK BAMA KICK posted:

I don't even know what the _* operator does. When I compile:

_* (the one-eyed man operator) is mildly useful:

code:
def foo(someStrings: String*) = someStrings mkString " "
foo(Seq("some", "dumb", "goon"):_*) // some dumb goon, liked you'd called foo("some", "dumb", "goon") instead
It only works with varargs, though, so if you

code:
def foo(a: String, b: String, c: String) = s"$a $b $c"
foo(Seq("some", "dumb", "goon"):_*)

not enough arguments for method foo: (a: String, b: String, c: String)String.
Unspecified value parameters b, c.
foo(Seq("some", "dumb", "goon"):_*);}
   ^

Adbot
ADBOT LOVES YOU

Cabbage Disrespect
Apr 24, 2009

ROBUST COMBAT
Leonard Riflepiss
Soiled Meat
edit: :saddowns:

code:
sealed trait Light
case class RedLight(timeLeft: Double) extends Light
case class GreenLight(timeLeft: Double) extends Light

def whatever(light: Option[Light]) = light match {
  case Some(r@RedLight(t)) => redLightStuff(r, t)
  case Some(g@GreenLight(t)) => greenLightStuff(g, t)
  case None => fuckOff
}

Cabbage Disrespect
Apr 24, 2009

ROBUST COMBAT
Leonard Riflepiss
Soiled Meat

InAndOutBrennan posted:

Best I came up with is, pseudocodish:
code:
Iterator[Tuple2[String, String]]
	.toList // Iterator has no group by
	.groupBy(t => t._1) // Now we have a Map[String, List[Tuple2[String, String]]]
	.mapValues(tupleList => tupleList.map(t => t._2)) // Now we have a Map[String, List[String]]
	.mapValues(stringList => new TreeSet[String] ++ stringList) // Create a new TreeSet and add everything from the list to it
For code that actually runs an example is (starting with the List though, you can do a.iterator first to get the exact same starting point I have):
code:
val a = List(Tuple2("a", "1"), Tuple2("a", "2"), Tuple2("b", "1"), Tuple2("b", "2"), Tuple2("b", "3"))
val b = a.groupBy(t => t._1).mapValues(v => v.map(v => v._2)).mapValues(v => TreeSet[String] ++ v)
Which works, but is horribly slow compared to bringing in a java.util.HashMap and java.util.TreeSet and doing it much less elegantly. Horribly slow in this case for comparison is that the Scala approach hadn't finished doing a single task out of ~200 in 30 minutes while the Javabased approach finish in approx 6 minutes.

So im guessing I'm missing something obvious here and I'm creating way too many objects/maps/lists or something.

You can:
code:
val brennansMap = foldLeft(Map[String, TreeSet[String]]().withDefaultValue(TreeSet.empty)) { build yo map up by matching in here }
but I make no guarantees about that being faster (and am on my phone anyway, so in my goony laziness I've decided that checking it is too hard).

For the general pattern of "gee I have to transform my collection into these intermediate collections and I wish that I didn't", check out collection.breakOut (but as you're doing that to get groupBy here, it's not really helpful, just good to know). When you're doing really performance-critical stuff, sometimes the easiest option is to bite the bullet, do the disgusting mutable thing, then wrap it in immutable functional ivory towers so that nobody else has to see what you've done.

  • Locked thread