k06a
k06a

Reputation: 18805

Mapping elements in an NSArray to their counts and getting the most frequent

I am working on presentation where I am comparing collections and algorithms of standard libraries of different languages. Help me to write effective and readable algorithm of this problem:

Metaprogramming language:

struct Tweet { id, time, text, url, user_id };
struct User { id, name, nick };
array<Tweet> tweets;
map<int, User> userDict;

Problem:

Find the user name who sent the greatest number of tweets with url field not equal to nil. Also find the count of such tweets from this user.

I have started like this:

NSMutableDictionary * countByUserId = [NSMutableDictionary dictionary];
foreach (Tweet * tweet in tweets)
    if (tweet.url != 0)
        countByUserId[tweet->user_id] = @(countByUserId[tweet->user_id] + 1);

Now I need to find key-value with max value.

This is my C++ code:

map<int,int> countByUserId;
for (auto it = tweets.begin(); it != tweets.end(); ++it)
    if (it->url != 0)
        countByUserId[it->user_id]++;

auto para = max_element(countByUserId.begin(),
                        countByUserId.end(),
                        [](pair<int,int> a, pair<int,int> b)
                        { return a.second < b.second; });

cout << "User = "  << userDict[para.first].name << endl
     << "Value = " << para.second << endl;

Upvotes: 2

Views: 131

Answers (1)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726809

Now I need to find key-value with max value...

There may be ties, so you should look for all key-value pairs with the max value. You can compute the max in your loop, and then walk through the NSDictionary again, looking for it:

NSMutableDictionary * countByUserId = [NSMutableDictionary dictionary];
NSInteger max = -1;
foreach (Tweet * tweet in tweets) {
    if (tweet.url != 0) {
        int next = countByUserId[tweet->user_id].intValue + 1;
        countByUserId[tweet->user_id] = @(next);
        if (next > max) {
            max = next;
        }
    }
}
[countByUserId enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
    if ([obj intValue] == max) {
        NSLog(@"Found max for user: %@", key);
    }
}

Upvotes: 1

Related Questions