implement a multiset/bag as Scala collection - scala

Inspired by this question, I'd like to implement a Multiset in Scala. I'd like a MultiSet[A] to:
Support adding, removing, union, intersection and difference
Be an A => Int, providing the count of each element
Here's one approach, extending Set:
import scala.collection.immutable.Map
import scala.collection.immutable.Set
import scala.collection.SetLike
import scala.collection.mutable.Builder
class MultiSet[A](private val counts: Map[A, Int] = Map.empty[A, Int])
extends SetLike[A, MultiSet[A]] with Set[A] {
override def +(elem: A): MultiSet[A] = {
val count = this.counts.getOrElse(elem, 0) + 1
new MultiSet(this.counts + (elem -> count))
}
override def -(elem: A): MultiSet[A] = this.counts.get(elem) match {
case None => this
case Some(1) => new MultiSet(this.counts - elem)
case Some(n) => new MultiSet(this.counts + (elem -> (n - 1)))
}
override def contains(elem: A): Boolean = this.counts.contains(elem)
override def empty: MultiSet[A] = new MultiSet[A]
override def iterator: Iterator[A] = {
for ((elem, count) <- this.counts.iterator; _ <- 1 to count) yield elem
}
override def newBuilder: Builder[A,MultiSet[A]] = new Builder[A, MultiSet[A]] {
var multiSet = empty
def +=(elem: A): this.type = {this.multiSet += elem; this}
def clear(): Unit = this.multiSet = empty
def result(): MultiSet[A] = this.multiSet
}
override def seq: MultiSet[A] = this
}
object MultiSet {
def empty[A]: MultiSet[A] = new MultiSet[A]
def apply[A](elem: A, elems: A*): MultiSet[A] = MultiSet.empty + elem ++ elems
def apply[A](elems: Seq[A]): MultiSet[A] = MultiSet.empty ++ elems
def apply[A](elem: (A, Int), elems: (A, Int)*) = new MultiSet((elem +: elems).toMap)
def apply[A](elems: Map[A, Int]): MultiSet[A] = new MultiSet(elems)
}
Extending Set is nice, because it means that MultiSet automatically gets definitions for union, difference, etc. All the following will hold:
// add
assert(
MultiSet("X" -> 3, "Y" -> 1) + "X" ===
MultiSet("X" -> 4, "Y" -> 1))
assert(
MultiSet("X" -> 3, "Y" -> 1) + "Z" ===
MultiSet("X" -> 3, "Y" -> 1, "Z" -> 1))
// remove
assert(
MultiSet("a" -> 2, "b" -> 5) - "b" ===
MultiSet("a" -> 2, "b" -> 4))
assert(
MultiSet("a" -> 2, "b" -> 5) - "c" ===
MultiSet("a" -> 2, "b" -> 5))
// add all
assert(
MultiSet(10 -> 1, 100 -> 3) ++ MultiSet(10 -> 1, 1 -> 7) ===
MultiSet(100 -> 3, 10 -> 2, 1 -> 7))
// remove all
assert(
MultiSet("a" -> 2, "b" -> 5) -- MultiSet("a" -> 3) ===
MultiSet("b" -> 5))
However, I would have to override some inherited methods like union and intersect because they would do the wrong things for multisets, e.g. the following would not hold:
// union (takes max of values)
assert(
MultiSet(10 -> 5, 1 -> 1).union(MultiSet(10 -> 3, 1 -> 7)) ===
MultiSet(10 -> 5, 1 -> 7))
// intersection (takes min of values)
assert(
MultiSet(10 -> 5, 100 -> 3).intersect(MultiSet(10 -> 1, 1 -> 7)) ===
MultiSet(10 -> 1))
Another problem with extending Set is that then I can't have MultiSet be an A => Int because I'll get the error: illegal inheritance; class MultiSet inherits different type instances of trait Function1: A => Int and A => Boolean. I could work around this by declaring a separate, say, count method, but I'd really prefer that the class just be an A => Int.
Another approach would be to inherit from Map[A, Int], which would give me the A => Int that I want, but then I would have to define all of my own ++, --, etc. since in Map these would be defined over (A, Int) pairs, but for a multiset they need to be defined over As.
I guess a third approach would be to give up on both Set and Map, and just implement a new subclass of Iterable or whatever.
What would you recommend? What's the best way to fit a MulitSet within the Scala collections framework?

However, I would have to override some inherited methods like intersect because they would do the wrong things for multisets
I think you'll have to bite the bullet and do just that.
Another problem with extending Set is that then I can't have MultiSet be an A => Int
Indeed, you cannot inherit twice the same trait (here Function1) with different type parameters. And actually in this case, this is not just an annoying technical limitation, but doing so would in fact not make much sense because when calling apply there would be no way to know which overload you want to call: def apply( key: A ): Boolean or def apply( key: A ): Int? You can't tell as the argument lists are the same.
However, what you could do is add an implicit conversion from MultiSet[A] to A => Int. This way, a MultiSet is treated by default as a A => Boolean (as any set), but can be coerced to a A => Int when nedded (in particular it could be passed directly to a function expecting a A => Int function).
class MultiSet[A] ... {
...
def count(elem: A): Int = counts.getOrElse( elem, 0 )
}
object MultiSet {
...
implicit def toCountFunc[A]( ms: MultiSet[A] ): A => Int = {
(x: A) => ms.count( x )
}
}
Some test i the REPL:
scala> val ms = MultiSet("a" -> 2, "b" -> 5)
ms: MultiSet[String] = Set(a, a, b, b, b, b, b)
scala> ms("a")
res17: Boolean = true
scala> ms("c")
res18: Boolean = false
scala> def testExists( f: String => Boolean, keys: String *) {
| println( keys.map( f ).toList )
| }
testExists: (f: String => Boolean, keys: String*)Unit
scala> testExists( ms, "a", "c" )
List(true, false)
scala> def testCounts( f: String => Int, keys: String *) {
| println( keys.map( f ).toList )
| }
testCounts: (f: String => Int, keys: String*)Unit
scala> testCounts( ms, "a", "c" )
List(2, 0)

Related

Calculate the number of occurrences of letters, and put the dictionaries in the list

I'm trying to count occurences of letters in the Stream of strings, and then put maps for each string ( "letter"-> count) in the List.
def checksum(ipt: Stream[String]) = ipt.foldLeft(List(Map("x"->1)))( (n:
List[Map[String, Int]], m: String) => n ++
m.split("").groupBy(identity).mapValues(_.size).toMap)
It gives problem:
Expression of type List[Equals] doesn't conform to expected type List[Map[String, Int]]
What's wrong? Like there is no problem with doing it for each string:
def checksum(ipt: Stream[String]) = ipt.foreach( (m: String) => println(m.split("").groupBy(identity).mapValues(_.size)))
It gives something like that on
val s = "bababc"
val d = "abbcde"
checksum(List(s,d).toStream)
out:
Map(b -> 3, a -> 2, c -> 1)
Map(e -> 1, a -> 1, b -> 2, c -> 1, d -> 1)
But how do i stash all this maps in the List now? I can't use vars and need to do it in one expression.
if you need a map for each string, you can achieve it with a map function over the first stream as follows:
def checksums(ipt: Stream[String]): Stream[Map[Char, Int]] = {
ipt.map(checksum)
}
def checksum(ipt: String): Map[Char, Int] = ipt.foldLeft(Map.empty[Char, Int]) { case (acc, ch) =>
acc.get(ch) match {
case Some(q) => acc + (ch -> (q + 1))
case None => acc + (ch -> 1)
}
}
Going back to your code, the operator to add an element to a List is :+, not ++.
++ is used to concatenate lists.
So you can fix your code like this:
def checksumFixed(ipt: Stream[String]) = {
ipt.foldLeft(List(Map("x"->1))) { (n: List[Map[String, Int]], m: String) =>
n :+ m.split("").groupBy(identity).mapValues(_.length)
}
}

Zip two HashMaps(or dictionaries)

What would be a functional way to zip two dictionaries in Scala?
map1 = new HashMap("A"->1,"B"->2)
map2 = new HashMap("B"->22,"D"->4) // B is the only common key
zipper(map1,map2) should give something similar to
Seq( ("A",1,0), // no A in second map, so third value is zero
("B",2,22),
("D",0,4)) // no D in first map, so second value is zero
If not functional, any other style is also appreciated
def zipper(map1: Map[String, Int], map2: Map[String, Int]) = {
for(key <- map1.keys ++ map2.keys)
yield (key, map1.getOrElse(key, 0), map2.getOrElse(key, 0))
}
scala> val map1 = scala.collection.immutable.HashMap("A" -> 1, "B" -> 2)
map1: scala.collection.immutable.HashMap[String,Int] = Map(A -> 1, B -> 2)
scala> val map2 = scala.collection.immutable.HashMap("B" -> 22, "D" -> 4)
map2: scala.collection.immutable.HashMap[String,Int] = Map(B -> 22, D -> 4)
scala> :load Zipper.scala
Loading Zipper.scala...
zipper: (map1: Map[String,Int], map2: Map[String,Int])Iterable[(String, Int, Int)]
scala> zipper(map1, map2)
res1: Iterable[(String, Int, Int)] = Set((A,1,0), (B,2,22), (D,0,4))
Note using get is probably preferable to getOrElse in this case. None is used to specify that a value does not exist instead of using 0.
As an alternative to Brian's answer, this can be used to enhance the map class by way of implicit methods:
implicit class MapUtils[K, +V](map: collection.Map[K, V]) {
def zipAllByKey[B >: V, C >: V](that: collection.Map[K, C], thisElem: B, thatElem: C): Iterable[(K, B, C)] =
for (key <- map.keys ++ that.keys)
yield (key, map.getOrElse(key, thisElem), that.getOrElse(key, thatElem))
}
The naming and API are similar to the sequence zipAll.

How to implement a generic algorithm for any Traversable in Scala?

I'm implementing a generic algorithm to return a collection based on two other collections.
The problem can be simplified to
def add[Repr <: Traversable[_]](coll1: Repr, coll2: Repr) = coll1 ++ coll2
The problem occurred when I applied the algorithm on a collection A I've defined as
class A[T] extends Iterable[(Int,T)] with IterableLike[(Int,T), A[T]] { ... }
i.e., the type parameter of A is not the same as for the inherited Iterable. Map uses a similar approach.
Example with Map:
scala> val m1 = Map("a" -> 1, "b" -> 1, "c" -> 1)
m1: scala.collection.immutable.Map[java.lang.String,Int] = Map(a -> 1, b -> 1, c -> 1)
scala> val m2 = Map("a" -> 2, "c" -> 1)
m2: scala.collection.immutable.Map[java.lang.String,Int] = Map(a -> 2, c -> 1)
Applying add with m1 and m2 as parameters results in a List:
scala> add(m1,m2)
res3: Traversable[Any] = List((a,1), (b,1), (c,1), (a,2), (c,1))
...while the wanted result would be similar to using the ++ method directly:
scala> m1 ++ m2
res0: scala.collection.immutable.Map[java.lang.String,Int] = Map(a -> 2, b -> 1, c -> 1)
This problem does not occur using a collection B defined as:
class B[T] extends Iterable[T] with IterableLike[T, B[T]] { ... }
e.g., Queue is implemented in a similar way.
Example with Queue:
scala> val q1 = Queue(9,2,5)
q1: scala.collection.immutable.Queue[Int] = Queue(9, 2, 5)
scala> val q2 = Queue(7,3,1)
q2: scala.collection.immutable.Queue[Int] = Queue(7, 3, 1)
Applying add on q1 and q2 gives the wanted result:
scala> add(q1,q2)
res4: Traversable[Any] = Queue(9, 2, 5, 7, 3, 1)
Question:
Is there a way to implement add, such that the result will be the same as when using the ++ method directly, for all kinds of travesables (including collections implemented similar to Map)? I have been trying to implement an implicit CanBuildFrom in the companion object of class A, with no luck. It seems to me that the problem is with the algorithm, not the collection implementations since it does not work for Map either.
Given that add is nothing more than an alias for TraversableLike.++, the first step is too look at ++'s signature:
trait TraversableLike[+A, +Repr] extends ... {
...
def ++:[B >: A, That](that: TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That
...
}
Then all you have to do is to turn this into the first parameter, and that into the second parameter:
import collection.TraversableLike
import collection.generic.CanBuildFrom
def add[A, Repr, B >: A, That](coll1: TraversableLike[A, Repr], coll2: TraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
coll1 ++ coll2
}
UPDATE: I also investigated into what you would need to do to have A behave properly with respect to add. As it stands (without doing anything special ), add applied on instances of A returns an Iterable instead of an A:
import collection.{IterableLike, TraversableLike}
// Dummy `A` implementation, for illustration
class A[T]( val inner: Seq[(Int, T)] ) extends Iterable[(Int,T)] with IterableLike[(Int,T), A[T]] {
def iterator: Iterator[(Int, T)] = inner.iterator
override protected[this] def newBuilder: scala.collection.mutable.Builder[(Int, T),A[T]] = ???
def :+(elem: (Int, T) ): A[T] = new A[T]( inner :+ elem )
}
object A {
def apply[T]( elems: (Int, T)* ) = new A( elems )
}
val a1 = A( 1-> "one", 2 -> "two" )
val a2 = A( 3-> "three", 4 -> "four", 5 -> "five" )
add(a1, a2)
The result is:
res0: Iterable[(Int, String)] = List((1,one), (2,two), (3,three), (4,four), (5,five))
Here is what I cam up by tibkering with CanBuildFrom. I cannot warrant that this is the best example but it does work (by which I mean we get an A as result when calling add):
import collection.IterableLike
import collection.generic.CanBuildFrom
import collection.mutable.Builder
class A[T]( val inner: Seq[(Int, T)] ) extends Iterable[(Int,T)] with IterableLike[(Int,T), A[T]] {
def iterator: Iterator[(Int, T)] = inner.iterator
override protected[this] def newBuilder: scala.collection.mutable.Builder[(Int, T),A[T]] = new A.ABuilder[T]
def :+(elem: (Int, T) ): A[T] = new A[T]( inner :+ elem )
}
object A {
private val _empty = new A[Nothing]( Nil )
def empty[T]: A[T] = _empty.asInstanceOf[A[T]]
def apply[T]( elems: (Int, T)* ) = new A( elems )
class ABuilder[T] extends Builder[(Int,T), A[T]] {
protected var elems: A[T] = empty
def +=(x: (Int, T)): this.type = { elems = elems :+ x; this }
def clear() { elems = empty }
def result: A[T] = elems
}
implicit def canBuildFrom[T]: CanBuildFrom[A[_], (Int,T), A[T]] = new CanBuildFrom[A[_], (Int,T), A[T]] {
def apply(from: A[_]) = apply()
def apply() = new ABuilder[T]
}
}
Now the result is:
res0: A[String] = ((1,one), (2,two), (3,three), (4,four), (5,five))

Scala, extending the iterator

Im looking to extended the iterator to create a new method takeWhileInclusive, which will operate like takeWhile but include the last element.
My issue is what is best practice to extend the iterator to return a new iterator which I would like to be lazy evaluated. Coming from a C# background I normal use IEnumerable and use the yield keyword, but such an option doesn't appear to exist in Scala.
for example I could have
List(0,1,2,3,4,5,6,7).iterator.map(complex time consuming algorithm).takeWhileInclusive(_ < 6)
so in this case the takeWhileInclusive would only have resolve the predicate on the values until I get the a result greater than 6, and it will include this first result
so far I have:
object ImplicitIterator {
implicit def extendIterator(i : Iterator[Any]) = new IteratorExtension(i)
}
class IteratorExtension[T <: Any](i : Iterator[T]) {
def takeWhileInclusive(predicate:(T) => Boolean) = ?
}
You can use the span method of Iterator to do this pretty cleanly:
class IteratorExtension[A](i : Iterator[A]) {
def takeWhileInclusive(p: A => Boolean) = {
val (a, b) = i.span(p)
a ++ (if (b.hasNext) Some(b.next) else None)
}
}
object ImplicitIterator {
implicit def extendIterator[A](i : Iterator[A]) = new IteratorExtension(i)
}
import ImplicitIterator._
Now (0 until 10).toIterator.takeWhileInclusive(_ < 4).toList gives List(0, 1, 2, 3, 4), for example.
This is one case where I find the mutable solution superior:
class InclusiveIterator[A](ia: Iterator[A]) {
def takeWhileInclusive(p: A => Boolean) = {
var done = false
val p2 = (a: A) => !done && { if (!p(a)) done=true; true }
ia.takeWhile(p2)
}
}
implicit def iterator_can_include[A](ia: Iterator[A]) = new InclusiveIterator(ia)
The following requires scalaz to get fold on a tuple (A, B)
scala> implicit def Iterator_Is_TWI[A](itr: Iterator[A]) = new {
| def takeWhileIncl(p: A => Boolean)
| = itr span p fold (_ ++ _.toStream.headOption)
| }
Iterator_Is_TWI: [A](itr: Iterator[A])java.lang.Object{def takeWhileIncl(p: A => Boolean): Iterator[A]}
Here it is at work:
scala> List(1, 2, 3, 4, 5).iterator takeWhileIncl (_ < 4)
res0: Iterator[Int] = non-empty iterator
scala> res0.toList
res1: List[Int] = List(1, 2, 3, 4)
You can roll your own fold over a pair like this:
scala> implicit def Pair_Is_Foldable[A, B](pair: (A, B)) = new {
| def fold[C](f: (A, B) => C): C = f.tupled(pair)
| }
Pair_Is_Foldable: [A, B](pair: (A, B))java.lang.Object{def fold[C](f: (A, B) => C): C}
class IteratorExtension[T](i : Iterator[T]) {
def takeWhileInclusive(predicate:(T) => Boolean) = new Iterator[T] {
val it = i
var isLastRead = false
def hasNext = it.hasNext && !isLastRead
def next = {
val res = it.next
isLastRead = !predicate(res)
res
}
}
}
And there's an error in your implicit. Here it is fixed:
object ImplicitIterator {
implicit def extendIterator[T](i : Iterator[T]) = new IteratorExtension(i)
}
scala> List(0,1,2,3,4,5,6,7).toStream.filter (_ < 6).take(2)
res8: scala.collection.immutable.Stream[Int] = Stream(0, ?)
scala> res8.toList
res9: List[Int] = List(0, 1)
After your update:
scala> def timeConsumeDummy (n: Int): Int = {
| println ("Time flies like an arrow ...")
| n }
timeConsumeDummy: (n: Int)Int
scala> List(0,1,2,3,4,5,6,7).toStream.filter (x => timeConsumeDummy (x) < 6)
Time flies like an arrow ...
res14: scala.collection.immutable.Stream[Int] = Stream(0, ?)
scala> res14.take (4).toList
Time flies like an arrow ...
Time flies like an arrow ...
Time flies like an arrow ...
res15: List[Int] = List(0, 1, 2, 3)
timeConsumeDummy is called 4 times. Am I missing something?

mapValues on innermost map of nested maps

This inspiration for this question came when I tried to answer this one.
Say you have a sequence of data (may be from a CSV file for instance). groupBy can be used to analyze certain aspect of the data, grouping by column or a combination of columns. For instance:
val groups0: Map[String, Array[String]] =
seq.groupBy(row => row(0) + "-" + row(4))
If I then want to create sub-groups within the groups I can do
val groups1: Map[String, Map[String, Array[String]]] =
groups0.mapValues(row => row.groupBy(_(1))
If I want to do this more one time it gets really cumbersome:
val groups2 =
groups1.mapValues(groups => groups.mapValues(row => row.groupBy(_(2)))
So here is my question given an arbitrary nesting of Map[K0, Map[K1, ..., Map[Kn, V]]], how do you write a mapValues function that takes a f: (V) => B and applies to the innermost V to return a Map[K0, Map[K1, ..., Map[Kn, B]]]?
My first instinct said that handling arbitrary nesting in a type-safe way would be impossible, but it seems that it IS possible if you define a few implicits that tell the compiler how to do it.
Essentially, the "simple" mapper tells it how to handle the plain non-nested case, while "wrappedMapper" tells it how to drill down through one Map layer:
// trait to tell us how to map inside of a container.
trait CanMapInner[WrappedV, WrappedB,V,B] {
def mapInner(in: WrappedV, f: V => B): WrappedB
}
// simple base case (no nesting involved).
implicit def getSimpleMapper[V,B] = new CanMapInner[V,B,V,B] {
def mapInner(in: V, f: (V) => B): B = f(in)
}
// drill down one level of "Map".
implicit def wrappedMapper[K,V,B,InnerV,InnerB]
(implicit innerMapper: CanMapInner[InnerV,InnerB,V,B]) =
new CanMapInner[Map[K,InnerV], Map[K,InnerB],V,B] {
def mapInner(in: Map[K, InnerV], f: (V) => B): Map[K, InnerB] =
in.mapValues(innerMapper.mapInner(_, f))
}
// the actual implementation.
def deepMapValues[K,V,B,WrappedV,WrappedB](map: Map[K,WrappedV], f: V => B)
(implicit mapper: CanMapInner[WrappedV,WrappedB,V,B]) = {
map.mapValues(inner => mapper.mapInner(inner, f))
}
// testing with a simple map
{
val initMap = Map(1 -> "Hello", 2 -> "Goodbye")
val newMap = deepMapValues(initMap, (s: String) => s.length)
println(newMap) // Map(1 -> 5, 2 -> 7)
}
// testing with a nested map
{
val initMap = Map(1 -> Map("Hi" -> "Hello"), 2 -> Map("Bye" -> "Goodbye"))
val newMap = deepMapValues(initMap, (s: String) => s.length)
println(newMap) // Map(1 -> Map(Hi -> 5), 2 -> Map(Bye -> 7))
}
Of course, in real code the pattern-matching dynamic solution is awfully tempting thanks to its simplicity. Type-safety isn't everything :)
I'm sure there is a better way using Manifest, but pattern matching seems to distinguish Seq and Map, so here it is:
object Foo {
def mapValues[A <: Map[_, _], C, D](map: A)(f: C => D): Map[_, _] = map.mapValues {
case seq: Seq[C] => seq.groupBy(f)
case innerMap: Map[_, _] => mapValues(innerMap)(f)
}
}
scala> val group0 = List("fooo", "bar", "foo") groupBy (_(0))
group0: scala.collection.immutable.Map[Char,List[java.lang.String]] = Map((f,List(fooo, foo)), (b,List(bar)))
scala> val group1 = Foo.mapValues(group0)((x: String) => x(1))
group1: scala.collection.immutable.Map[_, Any] = Map((f,Map(o -> List(fooo, foo))), (b,Map(a -> List(bar))))
scala> val group2 = Foo.mapValues(group1)((x: String) => x(2))
group2: scala.collection.immutable.Map[_, Any] = Map((f,Map(o -> Map(o -> List(fooo, foo)))), (b,Map(a -> Map(r -> List(bar)))))
Edit:
Here's a typed version using higher-kinded type.
trait NestedMapValue[Z] {
type Next[X] <: NestedMapValue[Z]
def nextValues[D](f: Z => D): Next[D]
}
trait NestedMap[Z, A, B <: NestedMapValue[Z]] extends NestedMapValue[Z] { self =>
type Next[D] = NestedMap[Z, A, B#Next[D]]
val map: Map[A, B]
def nextValues[D](f: Z => D): Next[D] = self.mapValues(f)
def mapValues[D](f: Z => D): NestedMap[Z, A, B#Next[D]] = new NestedMap[Z, A, B#Next[D]] { val map = self.map.mapValues {
case x: B => x.nextValues[D](f)
}}
override def toString = "NestedMap(%s)" format (map.toString)
}
trait Bottom[A] extends NestedMapValue[A] {
type Next[D] = NestedMap[A, D, Bottom[A]]
val seq: Seq[A]
def nextValues[D](f: A => D): Next[D] = seq match {
case seq: Seq[A] => groupBy[D](f)
}
def groupBy[D](f: A => D): Next[D] = seq match {
case seq: Seq[A] =>
new NestedMap[A, D, Bottom[A]] { val map = seq.groupBy(f).map { case (key, value) => (key, new Bottom[A] { val seq = value })} }
}
override def toString = "Bottom(%s)" format (seq.toString)
}
object Bottom {
def apply[A](aSeq: Seq[A]) = new Bottom[A] { val seq = aSeq }
}
scala> val group0 = Bottom(List("fooo", "bar", "foo")).groupBy(x => x(0))
group0: NestedMap[java.lang.String,Char,Bottom[java.lang.String]] = NestedMap(Map(f -> Bottom(List(fooo, foo)), b -> Bottom(List(bar))))
scala> val group1 = group0.mapValues(x => x(1))
group1: NestedMap[java.lang.String,Char,Bottom[java.lang.String]#Next[Char]] = NestedMap(Map(f -> NestedMap(Map(o -> Bottom(List(fooo, foo)))), b -> NestedMap(Map(a -> Bottom(List(bar))))))
scala> val group2 = group1.mapValues(x => x.size)
group2: NestedMap[java.lang.String,Char,Bottom[java.lang.String]#Next[Char]#Next[Int]] = NestedMap(Map(f -> NestedMap(Map(o -> NestedMap(Map(4 -> Bottom(List(fooo)), 3 -> Bottom(List(foo)))))), b -> NestedMap(Map(a -> NestedMap(Map(3 -> Bottom(List(bar))))))))