2013-03-13 7 views
13

Ich habe ein NSArray und jedes Objekt im Array hat eine groupId und einen Namen. Jedes Objekt ist einzigartig, aber es gibt viele mit derselben groupId. Gibt es eine Möglichkeit, das Array auseinander zu reißen und neu aufzubauen, so dass die Namen in einem einzigen Objekt mit der entsprechenden groubId gruppiert werden? Hier ist, was zur Zeit das Array wie folgt aussieht:Erstellen Sie ein NSArray neu, indem Sie Objekte mit übereinstimmenden ID-Nummern gruppieren?

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"; 
    } 
) 

Dies ist, was ich möchte aussehen:

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"; 
    } 
) 

EDIT: Ich habe versucht, & mit vielen fehlgeschlagenen Versuchen, die meisten entlang der Linien so etwas wie diese (schlampig Erholung, aber eine Idee zu geben):

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++; 
} 

Antwort

32
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); 

Ausgang:

(
     { 
     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; 
    } 
) 
2

dieses für eine NSDictionary von NSArrays nennt. Es gibt keinen schnellen und eleganten Weg - Sie müssten durch die Quelle scrollen.

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"]]; 
} 

BEARBEITEN: bearbeitet, um den Datentyp des Schlüssels nicht anzunehmen.

+0

'NSString * ID = [NSNumber numberWithInt: [o objectForKey: @ "groupId"]];' 'numberWithInt 'nimmt ein' int' als Argument und gibt 'NSNumber' zurück. Sie stellen ein 'id' Argument zur Verfügung und weisen es' NSString' zu. – Sebastian

1

Dies ist ähnlich wie Seva Antwort, aber es kann als Kategorie-Methode auf NSArray hinzugefügt:

/// @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]; 
} 

Und Sie können es wie so verwenden:

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

Dies ist nicht t genau das gleiche wie die ursprüngliche Antwort, da es das Personenwörterbuch als die Werte in dem Array erhalten wird, aber Sie können dann nur die Namenseigenschaft davon lesen.

1

Schnelle Implementierung der Antwort von Sergey für meine Kollegen 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) 

Beachten Sie das @ -Zeichen in ValueForKeyPath. dass stolperte mir ein wenig :)

0

Der Code unten nach oben wird eine NSArray Rebuild durch die Gruppierung von Objekten in jedem Wörterbuch in diesem Array von Wörterbuch-Array wieder

//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); 

// Konvertieren von beliebigen passenden Schlüssel wrt .. .

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

Hoffe, dass es helfen kann ..

Verwandte Themen