NSDictionary: преобразовать ключи NSString в нижний регистр, чтобы найти в них строку - PullRequest
3 голосов
/ 03 июня 2010

Я разрабатываю приложение для iPhone.

Я использую NSDictionary для хранения названий городов в качестве ключа и населения в качестве значения. Я хочу найти ключи, используя строчные буквы.

Я использую это:

NSDictionary *dict;

[dict objectForKey:[[city stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] lowercaseString]];

Но это не работает.

Я знаю, я могу сделать для, преобразовать ключи в нижний регистр и сравнить с городом.

Есть ли другой способ сделать это? Может быть, с помощью метода NSDictionary.

ОБНОВЛЕНИЕ
NSDictionary загружается из списка свойств.

Спасибо.

Ответы [ 4 ]

6 голосов
/ 03 июня 2010

Я использую этот метод в категории NSDictionary.

@implementation NSDictionary (MyCategory)
- (NSDictionary *)dictionaryWithLowercaseKeys {
    NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity:0];
    NSString *key;

    for (key in self) {
        [result setObject:[self objectForKey:key] forKey:[key lowercaseString]];
    }

    return result;
}
@end
1 голос
/ 03 июня 2010

Хотя мне все еще неясно, что вы хотите, этот цикл с поиском ключей без учета регистра. Получить значение этого ключа тогда тривиально.

for key in dict
{
    if ([key caseInsensitiveCompare: @"Whatever"] == NSOrderedSame)
        NSLog(@"They are equal.");
}
0 голосов
/ 27 марта 2014

Вышеприведенные ответы работают только для плоского словаря без какой-либо вложенности. Я создал категорию, которая создает копию существующего NSDictionary с каждым ключом, преобразованным в нижний регистр.

Заголовок : NSDictionary + LowercaseKeys.h

#import <Foundation/Foundation.h>

@interface NSDictionary (LowercaseKeys)

/*
 Recursive algorithm to find all nested dictionary keys and create an NSMutableDictionary copy with all keys converted to lowercase.
 Returns an NSMutableDictionary with all keys and nested keys converted to lowercase.
 */
+ (NSMutableDictionary *)dictionaryWithLowercaseKeysFromDictionary:(NSDictionary *)dictionary;

/*
 Convienience method to create a new lowercase dictionary object an existing NSDictionary instance
 Returns an NSMutableDictionary with all keys and nested keys converted to lowercase.
 */
- (NSMutableDictionary *)dictionaryWithLowercaseKeys;

@end

Реализация : NSDictionary + LowercaseKeys.m

#import "NSDictionary+LowercaseKeys.h"

@implementation NSDictionary (LowercaseKeys)

/*
 Recursive algorithm to find all nested dictionary keys and create an NSMutableDictionary copy with all keys converted to lowercase
 Returns an NSMutableDictionary with all keys and nested keys converted to lowercase.
 */
+ (NSMutableDictionary *)dictionaryWithLowercaseKeysFromDictionary:(NSDictionary *)dictionary
{
    NSMutableDictionary *resultDict = [NSMutableDictionary dictionaryWithCapacity:[dictionary count]];
    [dictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) {
        // There are 3 types of objects to consider, NSDictionary, NSArray and everything else
        id resultObj;
        if ([obj isKindOfClass:NSDictionary.class])
        {
            // Recursively dig deeper into this nested dictionary
            resultObj = [NSMutableDictionary dictionaryWithLowercaseKeysFromDictionary:obj];
        }
        else if ([obj isKindOfClass:NSArray.class])
        {
            /*
             Iterate over this nested NSArray. Recursively convert any NSDictionary objects to the lowercase version.
             If the array contains another array then continue to recursively dig deeper.
            */
            resultObj = [NSMutableArray arrayWithCapacity:[obj count]];
            for (id arrayObj in obj)
            {
                if ([arrayObj isKindOfClass:NSDictionary.class])
                    [resultObj addObject:[NSMutableDictionary dictionaryWithLowercaseKeysFromDictionary:arrayObj]];
                else if ([arrayObj isKindOfClass:NSArray.class])
                    [resultObj addObject:[NSMutableDictionary arrayWithLowercaseKeysForDictionaryArray:arrayObj]];
                else
                    [resultObj addObject:arrayObj];
            }
        }
        else
        {
            // The object is not an NSDictionary or NSArray so keep the object as is
            resultObj = obj;
        }

        // The result object has been converted and can be added to the dictionary. Note this object may be nested inside a larger dictionary.
        [resultDict setObject:resultObj forKey:[key lowercaseString]];
    }];
    return resultDict;
}

/*
 Convienience method to create a new dictionary object with all lowercase keys from an existing instance
 */
- (NSMutableDictionary *)dictionaryWithLowercaseKeys
{
    return [NSMutableDictionary dictionaryWithLowercaseKeysFromDictionary:self];
}

#pragma mark - Private helpers

/*
 Convert NSDictionary keys to lower case when embedded in an NSArray
 */
+ (NSMutableArray *)arrayWithLowercaseKeysForDictionaryArray:(NSArray *)dictionaryArray
{
    NSMutableArray *resultArray = [NSMutableArray arrayWithCapacity:[dictionaryArray count]];
    for (id eachObj in dictionaryArray)
    {
        if ([eachObj isKindOfClass:NSDictionary.class])
            [resultArray addObject:[NSMutableDictionary dictionaryWithLowercaseKeysFromDictionary:eachObj]];
        else if ([eachObj isKindOfClass:NSArray.class])
            [resultArray addObject:[NSMutableDictionary arrayWithLowercaseKeysForDictionaryArray:eachObj]];
    }
    return resultArray;
}

@end
0 голосов
/ 03 июня 2010

Я бы сказал, создать второй словарь. После загрузки из набора свойств выполните цикл по этому словарю и вставьте объекты во второй словарь. Преобразуйте ключи в нижний регистр, как вы идете. Затем выпустите первый словарь.

...