2013-04-11 3 views
0

나는 Videos의 배열을 가지고 있는데, 그 중에서도 특히 idtags 속성이 있습니다.일대 다 관계를 구축하는 가장 좋은 방법은 무엇입니까?

나는 그 keytag이며, 그 valueid 년대의 배열입니다 사전을 구축하고자합니다.

예를 들어, 일부 Video 객체는 다음과 같습니다

VideosWithTags["funny":[1]; "political":[1,2]; "humor":[1]; "america":[2]]

이 있습니까 :

Video{ id:1, tags:[funny,political,humor] }

Video{ id:2, tags:[political,america] }

나는 결과 사전과 같이 할 달성하기위한 표준 알고리즘 이?

현재 나는이 같은 일을 해요 :

for (NSDictionary *video in videos) 
{ 
    NSNumber *videoId = [video objectForKey:@"id"]; 
    NSArray *tags = [video objectForKey:@"tags"]; 

    for (NSString *tag in tags) 
    { 
     NSMutableArray *videoIdsForTag = nil; 

     if ([videosAndTags objectForKey:tag] != nil) //same tag with videoIds already exists 
     { 
      videoIdsForTag = [videosAndTags objectForKey:tag]; 
      [videoIdsForTag addObject:videoId]; 

      //add the updated array to the tag key 
      [videosAndTags setValue:videoIdsForTag forKey:tag]; 
     } 
     else //tag doesn't exist yet, create it and add the videoId to a new array 
     { 
      NSMutableArray *videoIds = [NSMutableArray array]; 
      [videoIds addObject:videoId]; 

      //add the new array to the tag key 
      [videosAndTags setObject:videoIds forKey:tag]; 
     } 
    } 
} 
+0

그 코드는 나에게 완벽하게 합리적인 보이는

는 (나는 그들이이에게 사물의 기능적 프로그래밍 스타일을 호출 생각하지만, 난 그렇게 확실하지 않다). 개선이 필요하다고 생각하는 부분이 있습니까? 조금 더 짧게 만드는 것은 리팩토링하기 쉽지만, 성능을 상당히 바꿀 수는 없습니다. –

+0

특히, 무엇보다 호기심. –

답변

1

당신이 새로운 리터럴 구문을 사용하여 작은 청소기를 볼 수 있습니다.

if 브랜치를 줄임으로써 이익을 얻을 수 있다고 생각합니다. 예 : 를 생성하고 videosAndTags 객체에 추가 한 다음이 시점 이후의 코드 논리

for (NSDictionary *video in videos) { 
    NSNumber *videoId = video[@"id"]; 
    NSArray *tags = video[@"tags"]; 

    for (NSString *tag in tags) { 
    NSMutableArray *videoIds = videosAndTags[tag]; 
    if (!videoIds) { 
     videoIds = [NSMutableArray array]; 
     videosAndTags[tag] = videoIds; 
    } 

    // This is the only line where I manipulate the array 
    [videoIds addObject:videoId]; 
    } 
} 
+0

니스. 이게 내가 찾는거야. 그 리터럴에 대해 몰랐어요! –

1
NSArray* videos = 
    @[@{ @"id" : @1, @"tags" : @[ @"funny", @"political", @"humor" ] }, 
     @{ @"id" : @2, @"tags" : @[ @"political", @"america" ] } ]; 
NSMutableDictionary* videosAndTags = [NSMutableDictionary new]; 

// find distinct union of tags 
NSArray* tags = [videos valueForKeyPath: @"@distinctUnionOfArrays.tags"]; 

// for each unique tag 
for(NSString* tag in tags) 
{ 
    // filter array so we only have ones that have the right tag 
    NSPredicate* p = [NSPredicate predicateWithFormat: @"tags contains %@", tag]; 
    videosAndTags[ tag ] = [[videos filteredArrayUsingPredicate: p] valueForKeyPath: @"id"]; 
} 
없이 중복과 일치 할 수 있습니다 - 당신은 존재하지 않는 경우 다음 videoIds 배열을 검색하려고 더 나은 것

NSPredicate 및 valueForKeyPath를 사용하는 또 다른 방법이 있습니다.

저는 자주 사용하지 않지만 때로는 유용하다고 증명할 수 있습니다.

NSPredicate reference
Key Value Coding

관련 문제