2

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 :)

2
  • Thanks a lot for every answer. I think I was able to solve it now :) Commented Apr 22, 2015 at 7:55
  • 3
    What I don't get is the title of the question, what's the deal with sorting? The question is more related to counting. Maybe use a more specific title for the sake of future generations? Commented Apr 22, 2015 at 8:24

3 Answers 3

2

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).

Sign up to request clarification or add additional context in comments.

Comments

2

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.

Comments

2

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)))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.