Creating NSDictionary with Initial Name to Sort

2019-09-06 14:47发布

问题:

I'm trying to merge the code from this link into my own application while using my own dictionary. I have had several problems, however.

My code produces this kind of dictionary (because I'm using a web service to get this data from a MySQL database):

{audiences = ({
            name = ABDUL;
            id = 1;
        },{
            name = ELSA;
            id = 2;
        },...etc)}

However, I want a dictionary like this:

audiences = @{@"B" : @[@"Bear", @"Black Swan", @"Buffalo"],
              @"C" : @[@"Camel", @"Cockatoo"],
              @"D" : @[@"Dog", @"Donkey"]};

Which, in my case, would appear like this:

audience = @{@"A":@[@"Abdul"],
             @"E":@[@"Elsa"]};

To summarize my problems: 1) How can I create an NSDictionary using only the names (no id)? 2) The dictionary including initial in it

Thanks for your help, I'm a newbie in Xcode and Objective-C, so please forgive me if I'm asking a noob question. Also, please bear with my bad English. Thanks in advance.

回答1:

So, your initial data structure received from the web service is (re-expressed in Cocoa):

NSDictionary* data = @{ @"audiences" : @[
                                          @{ @"name" : @"ABDUL",
                                             @"id" : @1 },
                                          @{ @"name" : @"ELSA",
                                             @"id" : @2 },
                                        ] };

You can build the data structure you describe like this:

NSMutableDictionary* audience = [NSMutableDictionary dictionary];
for (NSDictionary* person in data[@"audiences"])
{
    NSString* name = person[@"name"];
    if (![name length])
        continue;

    NSRange range = [name rangeOfComposedCharacterSequenceAtIndex:0];
    NSString* key = [[name substringWithRange:range] uppercaseString];
    NSMutableArray* list = audience[key];
    if (!list)
    {
        list = [NSMutableArray array];
        [audience setObject:list forKey:key];
    }
    [list addObject:name];
}


回答2:

I'm going to assume that you don't want the initials to be case sensitive.

NSArray *audiences = @[
                        @{ @"name" : @"ABDUL", @"id" : @1 },
                        @{ @"name" : @"ELSA", @"id" : @2 },
                        @{ @"name" : @"erik erikson", @"id" : @3 },
                        @{ @"name" : @"Leeroy Jenkins", @"id" : @-1 },
                        @{ @"name" : @"", @"id" : @4 },
                      ];

NSMutableDictionary *audienceMembersByInitial = [NSMutableDictionary dictionary];
for (NSDictionary *audienceMember in audiences) {
    NSString *name = audienceMember[@"name"];
    if (name.length > 0) {
        NSString *initial = [[name substringToIndex:1] uppercaseString];
        NSArray *audienceMembersWithInitial = audienceMembersByInitial[initial] ?: @[];
        audienceMembersByInitial[initial] = [audienceMembersWithInitial arrayByAddingObject:name];
    }
}
return [audienceMembersByInitial copy];

Output is...

@{
  @"A" : @[ @"ABDUL" ],
  @"E" : @[ @"ELSA", @"erik erikson" ],
  @"L" : @[ @"Leeroy Jenkins" ],
};