通过对具有匹配ID号的对象进行分组来重建NSArray?

问题描述:

我有一个NSArray,数组中的每个对象都有一个groupId和一个名字。每个对象都是唯一的,但有许多具有相同的groupId。有没有一种方法可以将数组拆分并重建它,以便将名称与相应的groubId分组为单个对象?以下是该数组目前的样子:通过对具有匹配ID号的对象进行分组来重建NSArray?

2013-03-12 20:50:05.572 appName[4102:702] the array: (
     { 
     groupId = 1; 
     name = "Dan"; 
    }, 
     { 
     groupId = 1; 
     name = "Matt"; 
    }, 
     { 
     groupId = 2; 
     name = "Steve"; 
    }, 
     { 
     groupId = 2; 
     name = "Mike"; 
    }, 
     { 
     groupId = 3; 
     name = "John"; 

    }, 
     { 
     groupId = 4; 
     name = "Kevin"; 
    } 
) 

这是我想它是什么样子:

2013-03-12 20:50:05.572 appName[4102:702] the array: (
     { 
     groupId = 1; 
     name1 = "Dan"; 
     name2 = "Matt"; 
    }, 
     { 
     groupId = 2; 
     name1 = "Steve"; 
     name2 = "Mike"; 
    }, 
     { 
     groupId = 3; 
     name = "John"; 

    }, 
     { 
     groupId = 4; 
     name = "Kevin"; 
    } 
) 

编辑: 我已经试过&失败,多次尝试,沿着最这样的东西(马虎娱乐,但给一个想法):

int idNum = 0; 
for (NSDictionary *arrObj in tempArr){ 
    NSString *check1 = [NSString stringWithFormat:@"%@",[arrObj valueForKey:@"groupId"]]; 
    NSString *check2 = [NSString stringWithFormat:@"%@",[[newDict valueForKey:@"groupId"]]; 
    if (check1 == check2){ 
     NSString *nameStr = [NSString stringWithFormat:@"name_%d",idNum]; 
     [newDict setValue:[arrObj valueForKey:@"name"] forKey:nameStr]; 
    } 
    else { 
     [newDict setValue:arrObj forKey:@"object"]; 
    } 
    idNum++; 
} 

NSArray *array = @[@{@"groupId" : @"1", @"name" : @"matt"}, 
        @{@"groupId" : @"2", @"name" : @"john"}, 
        @{@"groupId" : @"3", @"name" : @"steve"}, 
        @{@"groupId" : @"4", @"name" : @"alice"}, 
        @{@"groupId" : @"1", @"name" : @"bill"}, 
        @{@"groupId" : @"2", @"name" : @"bob"}, 
        @{@"groupId" : @"3", @"name" : @"jack"}, 
        @{@"groupId" : @"4", @"name" : @"dan"}, 
        @{@"groupId" : @"1", @"name" : @"kevin"}, 
        @{@"groupId" : @"2", @"name" : @"mike"}, 
        @{@"groupId" : @"3", @"name" : @"daniel"}, 
        ]; 

NSMutableArray *resultArray = [NSMutableArray new]; 
NSArray *groups = [array valueForKeyPath:@"@distinctUnionOfObjects.groupId"]; 
for (NSString *groupId in groups) 
{ 
    NSMutableDictionary *entry = [NSMutableDictionary new]; 
    [entry setObject:groupId forKey:@"groupId"]; 

    NSArray *groupNames = [array filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"groupId = %@", groupId]]; 
    for (int i = 0; i < groupNames.count; i++) 
    { 
     NSString *name = [[groupNames objectAtIndex:i] objectForKey:@"name"]; 
     [entry setObject:name forKey:[NSString stringWithFormat:@"name%d", i + 1]]; 
    } 
    [resultArray addObject:entry]; 
} 

NSLog(@"%@", resultArray); 

输出:

(
     { 
     groupId = 3; 
     name1 = steve; 
     name2 = jack; 
     name3 = daniel; 
    }, 
     { 
     groupId = 4; 
     name1 = alice; 
     name2 = dan; 
    }, 
     { 
     groupId = 1; 
     name1 = matt; 
     name2 = bill; 
     name3 = kevin; 
    }, 
     { 
     groupId = 2; 
     name1 = john; 
     name2 = bob; 
     name3 = mike; 
    } 
) 

这需要NSArrays的NSDictionary。没有快捷而优雅的方式 - 您必须滚动浏览源代码。

NSMutableDictionary *d = [NSMutableDictionary dictionaryWithCapacity:10]; //Or use alloc/init 
for(SomeObject o in appname) //What's the type of objects? you tell me 
{ 
    NSObject *ID = [o objectForKey: @"groupId"]; 
    NSMutableArray *a = [d objectForKey: ID]; 
    if(a == nil) 
    { 
     a = [NSMutableArray arrayWithCapacity: 10]; 
     [d setObject:a forKey: ID]; 
    } 
    [a addObject: [o objectForKey: @"name"]]; 
} 

编辑:编辑为不承担密钥的数据类型。

+0

'的NSString * ID = [NSNumber的numberWithInt:〔O objectForKey:@ “的groupId”]];''numberWithInt '接受'int'作为参数并返回'NSNumber'。你提供一个'id'参数并分配给'NSString'。 – Sebastian 2013-03-13 02:10:04

这与舍瓦的回答,但可以将其添加为NSArray的一类方法:

/// @return A dictionary of NSMutableArrays 
- (NSDictionary *)abc_groupIntoDictionary:(id<NSCopying>(^)(id object))keyFromObjectCallback { 
    NSParameterAssert(keyFromObjectCallback); 
    NSMutableDictionary *result = [NSMutableDictionary dictionary]; 
    for (id object in self) { 
     id<NSCopying> key = keyFromObjectCallback(object); 
     NSMutableArray *array = [result objectForKey:key]; 
     if (array == nil) { 
      array = [NSMutableArray new]; 
      [result setObject:array forKey:key]; 
     } 
     [array addObject:object]; 
    } 
    return [result copy]; 
} 

而且你可以使用它像这样:

NSDictionary *groups = [people abc_groupIntoDictionary:^id<NSCopying>(NSDictionary *person) { 
    return person[@"groupId"]; 
}]; 

This isn' t与原始答案完全相同,因为它会将人字典保留为数组中的值,但是您可以只读取名称属性。

快速执行Sergery的答案,为我的同伴noobs。

class People: NSObject { 
    var groupId: String 
    var name : String 
    init(groupId: String, name: String){ 
     self.groupId = groupId 
     self.name = name 
    } 
} 


let matt = People(groupId: "1", name: "matt") 
let john = People(groupId: "2", name: "john") 
let steve = People(groupId: "3", name: "steve") 
let alice = People(groupId: "4", name: "alice") 
let bill = People(groupId: "1", name: "bill") 
let bob = People(groupId: "2", name: "bob") 
let jack = People(groupId: "3", name: "jack") 
let dan = People(groupId: "4", name: "dan") 
let kevin = People(groupId: "1", name: "kevin") 
let mike = People(groupId: "2", name: "mike") 
let daniel = People(groupId: "3", name: "daniel") 

let arrayOfPeople = NSArray(objects: matt, john, steve, alice, bill, bob, jack, dan, kevin, mike, daniel) 

var resultArray = NSMutableArray() 
let groups = arrayOfPeople.valueForKeyPath("@distinctUnionOfObjects.groupId") as [String] 


for groupId in groups { 
    var entry = NSMutableDictionary() 
    entry.setObject(groupId, forKey: "groupId") 
    let predicate = NSPredicate(format: "groupId = %@", argumentArray: [groupId]) 
    var groupNames = arrayOfPeople.filteredArrayUsingPredicate(predicate) 
    for i in 0..<groupNames.count { 
     let people = groupNames[i] as People 
     let name = people.name 
     entry.setObject(name, forKey: ("name\(i)")) 
    } 
    resultArray.addObject(entry) 
} 

println(resultArray) 

请注意valueForKeyPath中的@符号。绊倒我一点:)

以下的代码通过分组对象WRT任何匹配键在每个字典该数组

//only to a take unique keys. (key order should be maintained) 
NSMutableArray *aMutableArray = [[NSMutableArray alloc]init]; 

NSMutableDictionary *dictFromArray = [NSMutableDictionary dictionary]; 

for (NSDictionary *eachDict in arrOriginal) { 
    //Collecting all unique key in order of initial array 
    NSString *eachKey = [eachDict objectForKey:@"roomType"]; 
    if (![aMutableArray containsObject:eachKey]) { 
    [aMutableArray addObject:eachKey]; 
    } 

    NSMutableArray *tmp = [grouped objectForKey:key]; 
    tmp = [dictFromArray objectForKey:eachKey]; 

if (!tmp) { 
    tmp = [NSMutableArray array]; 
    [dictFromArray setObject:tmp forKey:eachKey]; 
} 
[tmp addObject:eachDict]; 

} 

//NSLog(@"dictFromArray %@",dictFromArray); 
//NSLog(@"Unique Keys :: %@",aMutableArray); 

// 从字典再次转换为阵列中重建一个NSArray .. 。

self.finalArray = [[NSMutableArray alloc]init]; 
for (NSString *uniqueKey in aMutableArray) { 
    NSDictionary *aUniqueKeyDict = @{@"groupKey":uniqueKey,@"featureValues":[dictFromArray objectForKey:uniqueKey]}; 
    [self.finalArray addObject:aUniqueKeyDict]; 
} 

希望它可以帮助..