Search code examples
rascal

How do I find the maximum value of a map in Rascal?


I have a map[str, int], and need to find the maximum int value in the map. Is it possible to get all values of a map as a list, and then do max(list)? Or something like that..


Solution

  • You can get back the values a couple of different ways. For reference, say we have the following map:

    rascal>map[str words, int counts] m =  ( "word1" : 3, "word2" : 10, "word3" : 4, "word4" : 10);
    map[str words, int counts]: ("word1":3,"word2":10,"word3":4,"word4":10)
    

    You could view this as holding words and the frequency with which they appear in a document. There are now several ways to get back the values. Since we gave the domain and range both names when we declared the type of m (words and counts, respectively), we can use those names to get back the values. For instance:

    rascal>m.words;
    set[str]: {"word1","word2","word3","word4"}
    

    gets back the keys, while:

    rascal>m.counts;
    set[int]: {10,3,4}
    

    gets back the values. You can also use "projection" notation, projecting out the keys or values, like so:

    rascal>m<0>;
    set[str]: {"word1","word2","word3","word4"}
    rascal>m<1>;
    set[int]: {10,3,4}
    

    This works even if we didn't add names to the domain and range in the type. A third option, which also works even when we don't add names, is you can use library functions from the Map library:

    rascal>import Map;
    ok
    rascal>domain(m);
    set[str]: {"word1","word2","word3","word4"}
    rascal>range(m);
    set[int]: {10,3,4}
    

    Now that we have a set with the values, you can use the max function in the Set library to find the biggest number:

    rascal>import Set;
    ok
    rascal>max(m.counts);
    int: 10
    

    You now have different options if what you really want is the key or keys with this value. The Map library contains a function called invert which will "flip" the keys and values. Since you could have multiple keys with the same value, this actually gives you a map from the value to all the keys that had this value. In our case, this looks like this:

    rascal>invert(m);
    map[int, set[str]]: (
      10:{"word2","word4"},
      3:{"word1"},
      4:{"word3"}
    )
    

    So, if we want to get back the words that have the maximum numeric value, we could do the following:

    rascal>invert(m)[max(m.counts)];
    set[str]: {"word2","word4"}