2009-08-19 2 views
1

현재 나의 iPhone 프로젝트에서 "이름"키의 첫 번째 문자로 하위 사전을 그룹화 한 사전을 만들었습니다. NSLog는 다음을 반환합니다. 각 초기 문자 키 아래에 "이름"키만 표시하는 동일한 사전을 만들고 싶습니다. 하위 사전에있는 항목 중 일부를 복사하는 가장 좋은 방법은 무엇입니까? ObjectForKey 메서드는 초기 문자 (예 : "B"또는 "C")에 대한 항목 만 선택합니다. 이 사실을 충분히 설명하지 않았다면 알려주십시오. 감사합니다.여러 개의 하위 사전이 포함 된 사전 복사 및 하위 사전의 특정 키만 반환

sectionedDictionaryByFirstLetter:{ 
B =  (
      { 
     Name = "B...A Name Starting with B"; 
     Image = "ImageName1.png"; 
     Text = "Some Text"; 
    } 
); 
C =  (
      { 
     Name = "C...A Name Starting with C"; 
     Image = "ImageName2.png"; 
     Text = "Some Text"; 
    } 
); 
N =  (
      { 
     Name = "N...A Name Starting with N"; 
     Image = "ImageName3.png"; 
     Text = "Some Text"; 

    }, 
      { 
     Name = "N...A Name Starting with N"; 
     Image = "ImageName4.png"; 
     Text = "Some Text"; 

    }, 
      { 
     Name = "N...A Name Starting with N"; 
     Image = "ImageName5.png"; 
     Text = "Some Text"; 

    } 
    ); 
} 

내가 찾고 최종 결과는 다음과 같습니다

sectionedDictionaryByFirstLetter:{ 
B =  (
      { 
     Name = "B...A Name Starting with B"; 
    } 
); 
C =  (
      { 
     Name = "C...A Name Starting with C"; 
    } 
); 
N =  (
      { 
     Name = "N...A Name Starting with N"; 
    }, 
      { 
     Name = "N...A Name Starting with N"; 
    }, 
      { 
     Name = "N...A Name Starting with N"; 
    } 
    ); 
} 

답변

1
NSMutableDictionary* newDict = [NSMutableDictionary dictionary]; 
for (NSString* key in sectionedDictionaryByFirstLetter) { 
    NSMutableArray* newList = [NSMutableArray array]; 
    [newDict setObject:newList forKey:key]; 
    for (NSDictionary* entry in [sectionedDictionaryByFirstLetter objectForKey:key]) { 
     NSString* name = [entry objectForKey:@"Name"]; 
     [newList addObject:[NSDictionray dictionaryWithObject:name forKey:@"Name"]]; 
    } 
} 
+0

저는 항상 키 - 열거 자 (enumerator)가 낭비라고 생각했습니다. 일반적으로 키를 반복하고 나중에 각 값을 "검색"작업으로 사용합니다. –

+0

도움에 감사드립니다. 작은 오타를 발견했습니다. objectWithKey는 objectForKey 여야합니다. 또한 newDict에 배열이 추가됩니까? 감사합니다. – Jonah

+0

다음은 작동하게하기 위해 끝낸 것입니다. NSString * name = [entryObjectForKey : @ "Name"]; [newList addObject : [NSDictionary dictionaryWithObject : name forKey : @ "Name"]]]; NSString * afirstLetterString = [name substringToIndex : 1]; [newDict setObject : 새 목록 forKey : afirstLetterString]; – Jonah

2

코어 재단은 훌륭한 기능, CFDictionaryApplyFunction (나는 그들이 너무 NSDictionary에 그 기능을 포팅 할)이있다. 그러나 NSDictionaryCFDictionary은 "무료 브리지"입니다. 즉, 무료로 브릿지를 전송할 수 있습니다.

그래서 해결책은 위의 CFDictionaryApplyFunction에서 사용되는 applier 함수 인 SaveName을 만드는 것입니다. 예 :

void SaveName(const void* key, const void* value, void* context) { 
    NSMutableDictionary* result = (NSMutableDictionary*) context; 
    NSDictionary* dataDict = (NSDictionary*) value; 
    NSString* letterKey = (NSString*) key; 
    [result setObject:[dataDict valueForKey:@"Name"] forKey:@letterKey]; 
} 

void main() { 

    NSDictionary* exampleDict = .. ; 
    NSMutableDictionary* resultDict = [NSMutableDictionary dictionary]; 
    CFDictionaryApplyFunction((CFDictionaryRef)exampleDict, SaveName, (void*)resultDict); 
    // now, the resultDict contains key-value pairs of letter-name! 
} 

내 코드는 "값"사전에 개체가 하나만 있다고 가정합니다. SaveName을 자신의 데이터 구조를 고려하여 변경할 수 있지만 기본적으로 그렇게하는 방법입니다.

+0

배열은 어디에 있습니까? –

+0

@ Nikolai : 하나의 객체 만 있다고 가정하고 다른 데이터 구조도 지원하도록 변경할 수 있습니다. 또한 답변에서 배열을 나중에 "newDict"에 추가하는 것을 잊었습니다 ... –

관련 문제