Duzzz
Duzzz

Reputation: 191

Scala troubles with sorting

I am still on studying period when it comes to scala and faces some problems that I would like to solve.

What I have at the moment is a Seq of items type X. Now I want to make a function that returns me a map of numbers mapped with set of items that appear on that original seq certain amount of time.

Here is small example what I want to do:

val exampleSeq[X]: Seq = [a, b, d, d, c, b, d]
val exampleSeq2[x]: Seq = [a, a, a, c, c, b, b, c]

myMagicalFunction(exampleSeq) returns Map[1 -> Set[a, c], 2 -> Set[b], 3 -> Set[d]]

myMagicalFunction(exampleSeq2) returns Map[2 -> Set[b], 3 -> Set[a, c]]

So far I have been able to create a function that maps the item with the times it appears:

function[X](seq: Seq[X]) = seq.groupBy(item => item).mapValues(_.size)

Return for my exampleSeq from that one is

Map(a -> 1, b -> 2, c -> 1, d -> 3) 

Thank you for answers :)

Upvotes: 2

Views: 92

Answers (3)

curious
curious

Reputation: 2928

You can write your function as :

def f[T](l: Seq[T]): Map[Int, Set[T]] = {
    l.map {
      x => (x, l.count(_ == x))
    }.distinct.groupBy(_._2).mapValues(_.map(_._1).toSet)
  }

val l = List("a","a","a","b","b","b","b","c","c","d","e")
f(l)
res0: Map[Int,Set[String]] = Map(2 -> Set(c), 4 -> Set(b), 1 -> Set(d, e), 3 -> Set(a))


scala> case class A(name:String,age:Int)
defined class A

scala> val l = List(new A("a",1),new A("b",2),new A("a",1),new A("c",1) )
l: List[A] = List(A(a,1), A(b,2), A(a,1), A(c,1))

scala> f[A](l)
res1: Map[Int,Set[A]] = Map(2 -> Set(A(a,1)), 1 -> Set(A(b,2), A(c,1)))

Upvotes: 2

maasg
maasg

Reputation: 37435

You are almost there! Departing from the collection element -> count, you only need a transformation to get to count -> Col[elem].

Lets say that freqItem = Map(a -> 1, b -> 2, c -> 1, d -> 3) you would do something like:

val freqSet = freqItem.toSeq.map(_.swap).groupBy(_._1).mapValues(_.toSet)

Note that we transform the Map into a Seq before swapping the (k,v) into (v,k) because mapping over a Map preserves the semantics of key uniqueness and you'd lose one of (1 -> a), (1 -> b) otherwise.

Upvotes: 2

elm
elm

Reputation: 20415

One approach, for

val a = Seq('a', 'b', 'd', 'd', 'c', 'b', 'd')

this

val b = for ( (k,v) <- a.groupBy(identity).mapValues(_.size).toArray ) 
        yield (v,k)

delivers

Array((2,b), (3,d), (1,a), (1,c))

and so

b.groupBy(_._1).mapValues(_.map(_._2).toSet)
res: Map(2 -> Set(b), 1 -> Set(a, c), 3 -> Set(d))

Note seq.groupBy(item => item) is equivalent to seq.groupBy(identity).

Upvotes: 2

Related Questions