Stanos
Stanos

Reputation: 169

loop through values of a nested map in a map

I would be really grateful if you could help me with that.

Map<String, Double> movieMap = new HashMap<String, Double>;
movieMap.add("MovieA", 3);
movieMap.add("MovieB", 5);
movieMap.add("MovieC", 4);
movieMap.add("MovieD", 3.5);
movieMap.add("MovieE", 2.5);

Map<String, Double> movieMap2 = new HashMap<String, Double>;
movieMap2.add("MovieA", 3.5);
movieMap2.add("MovieB", 2.5);
movieMap2.add("MovieC", 4.5);
movieMap2.add("MovieD", 2);
            .
            .
            .
Map<String, Double> movieMapi = new HashMap<String, Double>;
movieMap2.add("MovieA", 5);
movieMap2.add("MovieC", 1.5);
movieMap2.add("MovieD", 2);

Map<String, Map<String, Double>> userMap = new HashMap<String, Map<String, Double>>;
userMap.add("Nick", movieMap);
userMap.add("Bill", movieMap2);
           .
           .
           .
userMap.add("Tom", movieMapi);

What i want to do is to make a function compare(userA, userB) and put the common movies and their rates into a new Map. By way of example the output of compare(Nick,Tom) should be a Map with keys - values : {{"MovieA", {5,3}}, {"MovieC", {4,1.5}}, {"MovieD", {3.5,2}}}

It seems pretty hard for me to solve it..Can you please help me?
Thanks...

Upvotes: 1

Views: 3081

Answers (2)

sp00m
sp00m

Reputation: 48837

This should suit your needs:

public static Map<String, List<Double>> compare(Map<String, Map<String, Double>> userMap, String user1, String user2) {
    // get both users movies and rates
    Map<String, Double> user1Map = userMap.get(user1);
    Map<String, Double> user2Map = userMap.get(user2);
    // if at least one of the both users doesn't exists in the initial map
    if (null == user1Map || null == user2Map) {
        // exit
        throw new IllegalArgumentException();
    }
    // will contains the common movies and the respective rates to return
    Map<String, List<Double>> commonMovies = new HashMap<String, List<Double>>();
    // for each movie/rate of the first user
    for (Entry<String, Double> user1Entry : user1Map.entrySet()) {
        // try to find the same movie in the second user's map
        Double user2Value = user2Map.get(user1Entry.getKey());
        // if both contains the same movie
        if (null != user2Value) {
            // create a new list
            List<Double> rates = new LinkedList<Double>();
            // list.get(0) will always be the rate of the first user passed as a parameter to this method
            rates.add(user1Entry.getValue());
            // and list.get(1) the rate of the second one
            rates.add(user2Value);
            commonMovies.put(user1Entry.getKey(), rates);
        }
    }
    return commonMovies;
}

To call:

Map<String, List<Double>> commonMovies = compare(userMap, "Nick", "Tom");

Note that we usually ask the OP to give some code snippets he already tried before giving the solution, but I believe that iterating over maps (and nested maps) is quite hard for beginners, and a single commented solution is sometimes better than severals personal tries ;)

Upvotes: 2

jahroy
jahroy

Reputation: 22692

You can iterate over the keys in a map using the Map.keySet() method:

Set<String> nickKeys = userMap.get("Nick").keySet();
Set<String> tomKeys = userMap.get("Tom").keySet();

Your code might look something like this:

Map<String, Double> nickMap = userMap.get("Nick");
Map<String, Double> tomMap = userMap.get("Tom");

Map<String, List<Double>> commonMap = new HashMap<String, List<Double>>();

for (String movieName : nickMap.keySet()) {
    if (tomMap.containsKey(movieName)) {
        List<Double> tempList = new ArrayList<Double>();
        tempList.add(nickMap.get(movieName));
        tempList.add(tomMap.get(movieName));
        commonMap.put(movieName, tempList);
    }
}

Upvotes: 3

Related Questions