我有一组Videos
个对象,其中包括属性id
和tags
。
我想构建一个字典,其key
是tag
,其value
是id
的数组。
例如,某些Video
对象可能如下所示:
Video{ id:1, tags:[funny,political,humor] }
Video{ id:2, tags:[political,america] }
我希望结果字典看起来像这样:
VideosWithTags["funny":[1]; "political":[1,2]; "humor":[1]; "america":[2]]
是否有标准算法来实现这一目标?
目前我正在做这样的事情:
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 :(得分:1)
使用新的文字语法可以使这个看起来更清晰。
我认为通过让if
分支机构减少工作量,您可以从中受益。例如你最好尝试检索videoIds
数组,如果它不存在 - 创建它并将其添加到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];
}
}
答案 1 :(得分: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"];
}
这是使用NSPredicate和valueForKeyPath的另一种方法。
我不经常使用它们,但有时它们可以被证明是有用的。
(我认为他们称之为功能编程风格的东西,但我不太确定)