0

作为一个具体的例子,假设我有以下字典数组,它们共享相同的键和值类型:

[ {car: "Ferrari", make: "Italian", color: "red"},
  {car: "Ferrari", make: "Italian", color: "yellow"},
  {car: "Porsche", make: "German", color: "green"},
  {car: "Porsche", make: "German", color: "silver"}
]

我如何才能通过字典仅通过键(例如,通过“汽车”)进行搜索,然后将不同的值(在本例中为“颜色”)组合为数组,以便我的结果数组是:

[ {car: "Ferrari", make: "Italian", color: ["red", "yellow"]},
  {car: "Porsche", make: "German", color: ["green", "silver"]},
]

谢谢!

4

2 回答 2

1

以下方法将解决您的问题:

- (NSArray*) combineValuesFromArray:(NSArray*) array byKey: (NSString*) key
{
    NSMutableSet *differentValues = [NSMutableSet set];
    for(NSDictionary *dict in array)
    {
        [differentValues addObject:dict[key]];
    }
    NSMutableArray *result = [NSMutableArray array];
    for(NSString *value in differentValues)
    {
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", key, value];
        NSArray *filteredArray = [array filteredArrayUsingPredicate:predicate];
        NSMutableDictionary *sets = [NSMutableDictionary new];
        for(NSDictionary *dict in filteredArray)
        {
            for(NSString *dictKey in dict)
            {
                NSMutableSet *set = [sets[dictKey] mutableCopy];
                if(set == nil) set = [NSMutableSet new];
                [set addObject:dict[dictKey]];
                sets[dictKey] = set;
            }
        }
        NSMutableDictionary *newDict = [NSMutableDictionary new];
        for(NSString *dictKey in sets)
        {
            newDict[dictKey] = ([sets[dictKey] count] == 1) ? [sets[dictKey] anyObject] : [sets[dictKey] copy];
        }
        [result addObject:[newDict copy]];
    }
    return [result copy];
}

我使用以下代码进行测试:

NSString *car = @"car";
NSString *make = @"make";
NSString *color = @"color";
NSArray *array = @[ @{car: @"Ferrari", make: @"Italian", color: @"red"},
                  @{car: @"Ferrari", make: @"Italian", color: @"yellow"},
                  @{car: @"Porsche", make: @"German", color: @"green"},
                  @{car: @"Porsche", make: @"German", color: @"silver"}
                    ];
NSLog(@"%@", [self combineValuesFromArray:array byKey:car]);
于 2013-11-12T00:23:52.890 回答
1

这是我的方法,时间复杂度稍好一些。第一个函数convertDataBasedOnKey将接收您可能想要比较的值,正如您在想要通过 key 搜索的问题上所说的那样。第二个函数getSharedDictionaryOfElements仅用于创建具有合并值的最终字典。

- (void)convertDataBasedOnKey:(NSString *)baseKey {

    desiredFormatData = [[NSMutableArray alloc] init];

    NSMutableString *filterString = [NSMutableString stringWithFormat:@"(%@ ==",baseKey];
    [filterString appendString:@" %@)"];

    while (currentFormatData.count != 0) {

        NSDictionary *aDictionary = [currentFormatData firstObject];
        NSString *firstValue = [aDictionary objectForKey:baseKey];
        NSArray *filtered = [currentFormatData filteredArrayUsingPredicate:
                             [NSPredicate predicateWithFormat:filterString, firstValue]];
        NSDictionary *mergedDictionary = [self getSharedDictionaryOfElements:filtered sharingValueForKey:baseKey];
        [desiredFormatData addObject:mergedDictionary];

        [currentFormatData removeObjectsInArray:filtered];
    }

    NSLog(@"%@",desiredFormatData.description);
}

- (NSDictionary *)getSharedDictionaryOfElements:(NSArray *)anArray sharingValueForKey:(NSString *)aKey {

    if (!anArray || anArray.count == 0) {
        return nil;
    }
    // As all the elements in anArray share the same keys
    NSMutableDictionary *resultDictionary = [[NSMutableDictionary alloc] init];
    NSDictionary *modelDictionary = [anArray firstObject];

    for (NSString *aKey in modelDictionary.allKeys) {
        NSPredicate *filterByKey = [NSPredicate predicateWithValue:YES];
        NSArray *resultArray = [[anArray valueForKey:aKey] filteredArrayUsingPredicate:filterByKey];
        NSMutableArray *uniqueArray = [NSMutableArray arrayWithArray:[[NSSet setWithArray:resultArray] allObjects]];
        [resultDictionary setObject:uniqueArray forKey:aKey];
    }
    return resultDictionary;
}

例子

使用这两个函数来获得你所问的将是这样的:

声明了这两个变量后:

NSMutableArray *currentFormatData;
NSMutableArray *desiredFormatData;

然后用示例数据填充第一个并基于键“汽车”进行操作:

currentFormatData = [NSMutableArray arrayWithArray:@[@{@"car":@"Ferrari", @"make":@"Italian", @"color":@"red"},
                                                     @{@"car":@"Ferrari", @"make":@"Italian", @"color":@"yellow"},
                                                     @{@"car":@"Porsche", @"make":@"German", @"color":@"green"},
                                                     @{@"car":@"Porsche", @"make":@"German", @"color":@"silver"}]];

[self convertDataBasedOnKey:@"car"];
于 2013-11-12T00:53:24.820 回答