The Human Bagel
The Human Bagel

Reputation: 7224

iOS sort one array based on order of strings in another array

This is another very specific problem I am trying to solve.

I am pulling a list a twitter user accounts logged into the users settings application. This returns an array with the usernames in the correct order.

I then pass this array to this twitter API:

https://api.twitter.com/1.1/users/lookup.json

The returned array contain all the additional data I need for each user account logged in. The first array contains NSStrings (usernames), the returned array has been parsed to contain dictionaries that have a key and value for the username, name, and profile pic.

Problem now is that the order is completely different than the first array I passed.. This is expected behavior from Twitter, but it needs to be in the exact same order (I will be referencing the original index of the AccountStore which will match the first array, but not the new array of dictionaries).

How can I tell the new array to match the contained dictionaries to be the same order as the first array based on the username key?

I know this sounds confusing, so let me at least post the data to help.

Here is the first array output:

(
    kbegeman,
    indeedyes,
    soiownabusiness,
    iphonedev4me
)

Here is what the second array outputs:

(
        {
        image = "https://si0.twimg.com/profile_images/3518542448/3d2862eee546894a6b0600713a8de862_normal.jpeg";
        name = "Kyle Begeman";
        "screen_name" = kbegeman;
    },
        {
        image = "https://si0.twimg.com/profile_images/481537542/image_normal.jpg";
        name = "Jane Doe";
        "screen_name" = iPhoneDev4Me;
    },
        {
        image = "https://twimg0-a.akamaihd.net/profile_images/378800000139973355/787498ff5a80a5f45e234b79005f56b5_normal.jpeg";
        name = "John Doe";
        "screen_name" = indeedyes;
    },
        {
        image = "https://si0.twimg.com/sticky/default_profile_images/default_profile_5_normal.png";
        name = "Brad Pitt";
        "screen_name" = soiownabusiness;
    }
)

Due to the way Twitter returns the data, it is never the EXACT same order, so I have to check this every time I call these methods.

Any help would be great, would save my night. Thanks in advance!

Upvotes: 1

Views: 2890

Answers (4)

Tricertops
Tricertops

Reputation: 8512

You want the array of dictionaries be sorted by comparing screen_name value with your first array. Right? Also, the screen name may have different case than your username. Right?

I would use mapping dictionary:

  1. Create dictionary from screen name to user dictionary:

    NSArray *screenNames = [arrayOfUserDicts valueForKeyPath:@"screen_name.lowercaseString"];
    NSDictionary *userDictsByScreenName = [NSDictionary dictionaryWithObjects:arrayOfUserDicts forKeys:screenNames];
    
  2. Build final array by finding user dictionary for usernames in your array:

    NSMutableArray *sortedUserDicts = [NSMutableArray arrayWithCapacity:arrayOfUsernames.count];
    for (NSString *username in arrayOfUsernames) {
        NSDictionary *userDict = [userDictsByScreenName objectForKey:username.lowercaseString];
        [sortedUserDicts addObject:userDict];
    }
    

Upvotes: 6

Samet DEDE
Samet DEDE

Reputation: 1621

lets name your arrays as firstArray and secondArray.

NSArray *sortedArray = [secondArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        return [@([firstArray indexOfObject:[obj1 objectForKey:@"name"]]) compare:@([firstArray indexOfObject:[obj2 objectForKey:@"name"]])];
    }];

Upvotes: 0

Martin R
Martin R

Reputation: 539955

First generate a mapping that maps the "screen_name" to the corresponding dictionary in the second array:

NSDictionary *map = [NSDictionary dictionaryWithObjects:secondArray
                          forKeys:[secondArray valueForKey:@"screen_name"]];

Then you can create the sorted array with a single loop:

NSMutableArray *sorted = [NSMutableArray array];
for (NSString *name in firstArray) {
    [sorted addObject:map[name]];
}

Upvotes: 2

garrettmurray
garrettmurray

Reputation: 3368

That sort order isn't something that could be easily replicated (i.e. it's not alpha, etc). Instead, you should just use that original NSArray as a guide to match data from the NSDictionary from Twitter. For example:

[twitterDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
  NSInteger index = [yourLocalArray indexOfObject:obj];
  if (index != NSNotFound) {
    // You have a match, do something.
  }
}];

Upvotes: 0

Related Questions