3

I have a bit of a strange problem. So I have an array of dictionaries say,

(
Dict 1:
"Name" = "B"
"Number" = "2"

Dict 2:
"Name" = "A"
"Number" = "1"

Dict 3:
"Name" = "D"
"Number" = "4"

Dict 4:
"Name" = "C"
"Number" = "3"

Dict 5
"Name" = "E"
"Number" = "5"
)

And say I have an array:

(
"1"
"4"
"2"
)

How can I get an array that contains all the dictionaries that their "Number" key match each object in that array and have it sorted according to the second array?

e.g. output would be

(
Dict 1:
"Name" = "A"
"Number" = "1"

Dict 2:
"Name" = "D"
"Number" = "4"

Dict 3:
"Name" = "B"
"Number" = "2"
)

I think I can use sortedArrayUsingDescriptors but I'm not sure how to specify multiple descriptors. Can the descriptors contain every object in the array? Any help or guidance is much appreciated.

5
  • how about doing this 2 steps: 1. sort original dictionary with key = number 2. for each number in your array {1,4,2..}, do a bsearch in your sorted dictionary, if found then you print the details of that entry complexity = O(mlogm + nlogm) m = size of dictionary, n = size of query array Commented Mar 21, 2014 at 4:38
  • oh but something is unclear here, will your dictionary have two entries with same number? eg: Dict 1 { Name = A, number = 1} Dict 2 {Name = B, number = 1} If yes, then when you have 1 in your query array, should I print out both? Commented Mar 21, 2014 at 4:39
  • @shole What do you mean by bsearch? And do you mean sorted array not dictionary? Commented Mar 21, 2014 at 4:41
  • @shole No, there will not be duplicates in the number key. Commented Mar 21, 2014 at 4:41
  • I meant binary search, can you reorder your dictionary in anyway such that it's ascending with the Number? For example, I can make array of pairs [(1,2), (2,1), (3,4), (4,3),(5,5)] which is in form of (DictID, Number), then reorder it to [(2,1),(1,2),(4,3),(3,4),(5,5)]. Finally just do binary search of each query, say for query {1,4,2}, I can find (2,1), (3,4), (1,2) respectively, so you know you should print Dict2 , Dict3, Dict1 as output.. Commented Mar 21, 2014 at 4:48

4 Answers 4

3

This has nothing to do with sorting - especially since not every dictionary in the array is even involved. What you want to do is extract each dictionary from the array.

This would be a lot simpler if you didn't have an array of dictionaries at all. Instead, you should start with one big dictionary where the key is the number and the value is whatever (perhaps the whole dictionary, perhaps the name alone). Now you can just look up each number as the key into that dictionary and grab the name.

{ 1 => A, 2 => B, 3 => C ...}

Now just grab objectForKey:@1, objectForKey:@4, objectForKey:@2 and you're done.

Sign up to request clarification or add additional context in comments.

4 Comments

I'm pulling from a JSON request so I get an array of dictionaries. So unfortunately this will not work for me. +1 though.
I don't agree. You can make the dictionary I am describing from the data that you get! And you should do so, exactly in order to facilitate the lookup that you intend to do. Clever, eh?
This kind of re-jiggering in order to facilitate a certain kind of lookup is perfectly standard behavior.
Yeah, it's a clever method I agree. I'll see what I can do.
1
for (NSNumber *aNumber in testArray) {
    for (NSDictionary *aDict in anArray) {
        if (aNumber.intValue == [(NSNumber *)[aDict valueForKey:@"Number"]intValue]) {
            [finalArray addObject:aDict];
        }
    }
}

Comments

0

Here is the answer. here I used enumerator, which is faster

NSArray * dicArray = @[@{@"Name": @"B",@"Number":@"2"},
                       @{@"Name": @"A",@"Number":@"1"},
                       @{@"Name": @"D",@"Number":@"4"},
                       @{@"Name": @"C",@"Number":@"3"},
                       @{@"Name": @"E",@"Number":@"5"}];
NSArray * indArray = @[@(1),@(4),@(2)];

NSMutableArray * resultArray = [NSMutableArray arrayWithCapacity:indArray.count];
[indArray enumerateObjectsUsingBlock:^(NSNumber* SearchValue, NSUInteger idx, BOOL *stop) {

    //search dicArray for object, which match your condition (i.e Number value == obj value)
    NSInteger index = [dicArray indexOfObjectPassingTest:^BOOL(NSDictionary* obj, NSUInteger idx, BOOL *stop) {
        return ([(NSString *)obj[@"Number"] integerValue] == SearchValue.integerValue)? YES : NO;
    }];

    resultArray[idx] = dicArray[index];
}];

NSLog(@"%@",resultArray);

Comments

0

So I figured it out. Basically I used nested for-loops.

Here is the code. It may take a long time depending on how many objects are in each. For me I had about 30 objects each so it took about 50ms:

NSMutableArray *finalArray = [NSMutableArray array];
for (NSString *keyName in keyArray) {
    NSString *fname;
    for (NSDictionary *dict in dictArray) {
        fname = [dict objectForKey:@"theKey"];
        if ([fname isEqualToString:keyName])
            [finalArray addObject:dict];
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.