0

I'm trying to translate this algorithm I wrote in Java to Scala, but I'm having trouble with the containsValue() method that is present in Java. I want to do something like if (hashMap.containsValue(value)) but I have looked through the scala documentation and have only found a contains(key) method. How do you implement or use hashmap.containsValue(value) in Scala I'm still new to Scala, but here's what I have so far in Scala:

def retString(s: String)
{
  val map = new mutable.HashMap[Int, Char]
  for (c <- s.toCharArray)
  {
      //if(!map.containsValue(c)) goes here
  }

}

` The full algorithm I'm trying to convert is removeDuplicates I wrote in Java:

public static String removeDuplicates(char[] s)
{

    HashMap<Integer, Character> hashMap = new HashMap<Integer, Character>();
    int current = 0;
    int last = 0;
    for(; current < s.length; current++)
    {
         if (!(hashMap.containsValue(s[current])))
         {
              s[last++] = s[current];
              hashMap.put(current, s[current]);

         }
    }
    s[last] = '\0';
    //iterate over the keys and find the values
    String result = "";
    for (Integer key: hashMap.keySet()) {
        result += hashMap.get(key);
    }
    return result;

}
Govind Singh
  • 15,282
  • 14
  • 72
  • 106
John61590
  • 1,106
  • 1
  • 13
  • 29
  • 2
    Hey, Why don't you also add the java algo you wish to convert? Will help us understand what you are trying to do? – Michael W Jul 18 '14 at 12:21
  • Usually, for this kind of `removeDuplicates` algorithm, one creates a *set* of the things you are trying to deduplicate. the containsValue method is O(n), and thus your algorithm is O(n^2). You can do it in O(n log(n)) with a set (even if you also keep a map of indexes to values to keep the ordering). – Will Fitzgerald Jul 18 '14 at 13:53
  • @WillFitzgerald ? It's O(2n) not O(n^2). O(n) if you're not counting the print out. – John61590 Jul 18 '14 at 14:37
  • You have to do O(n) comparisons for each item, so it's O(n^2). What am I missing? – Will Fitzgerald Jul 18 '14 at 15:27

4 Answers4

5

You can use exists:

map.values.exists(_ == c)
arshajii
  • 127,459
  • 24
  • 238
  • 287
  • @John61590 We're creating a 1-argument lambda function that tests for equality between its one argument and `c`. See: http://www.scala-lang.org/old/node/133. – arshajii Jul 18 '14 at 12:42
1

to get know hashmap contaning this value you can use

hashMap.exists(_._2 == c)

you want something like this java to scala ;)

def removeDuplicates(s: Array[Char]): String = {
    val hashMap = new scala.collection.mutable.HashMap[Integer, Character]()
    var c = 0
    var last = 0
    while (c< s.length) {
      if (!(hashMap.exists(_._2 == c))){
        last+=1
        s(last) = s(c)
        hashMap.put(c, s(c))
      }
      c += 1
    }
    s(last) = '\0'
    var result = ""
    for (key <- hashMap.keySet) {
      result += hashMap.get(key)
    }
    result
  }
Govind Singh
  • 15,282
  • 14
  • 72
  • 106
  • There's no current variable used in this code. Also, keySet doesn't seem to be getting the chars in the right order and result is returning Some(character) instead of the whole string. – John61590 Jul 18 '14 at 14:33
  • @John61590 oops i just converted according to OP and i forgot the `current` in `if` – Govind Singh Jul 18 '14 at 14:38
0

containsValue is never going to be an efficient operation as it cannot use any of the special magic in HashMap.

As a result you can just iterate over the collection of values yourself and achieve exactly the same performance.

i.e. in Java:

for (Ob ob: map.values()) {
    if (search.equals(ob))
       return search;
}

Or alternatively just:

map.values().contains(search);
Tim B
  • 40,716
  • 16
  • 83
  • 128
0

You might be glad to know that Scala collections contain a distinct method:

> List(1,1,1,2,3,3,2,1).distinct
> List(1,2,3)

There is a Stack Overflow discussion on implementing distinctBy which is somewhat useful to look at.

Community
  • 1
  • 1
Will Fitzgerald
  • 1,372
  • 10
  • 14