Noob在这里,可以使用一些帮助。
我有一张NSArray,里面装满了MPMediaItems(歌曲),我需要通过专辑来改组。我最终需要做的是:
1)按专辑分组曲目(未知专辑总数)。
2)按照曲目编号对专辑中的曲目进行排序。
3)返回一个包含所有曲目的新数组(按组随机分组,并按组中的数字顺序排列)。
我相信我知道如何通过一遍又一遍地遍历数组来做到这一点,但这看起来非常低效。我怀疑NSDictionary可能是更好的选择,但我甚至不知道从哪里开始。
非常感谢任何帮助!
麦克
答案 0 :(得分:1)
即使我没有使用MPMediaItems,我也可以解释NSArray的简单排序和过滤方式。
为了说明的目的,我正在创建一个名为Song的虚构类,它可能与MPMediaItem不相似。 Song类有两个属性,叫做albumName和trackNumber。然后我们添加一个名为+ (NSDictionary *)songsGroupedByAlbumAndSortedByTrack:(NSArray *)songs
的类方法,它接受一个Song对象数组并返回一个NSDictionary。返回的字典中的每个键都是一个albumName,相应的值将是属于该专辑的歌曲数组,并按曲目编号排序。
@interface Song : NSObject
@property (nonatomic, copy) NSString *albumName;
@property (nonatomic, assign) NSInteger trackNumber;
@end
@implementation Song
+ (NSDictionary *)songsGroupedByAlbumAndSortedByTrack:(NSArray *)songs {
NSSortDescriptor *byTrack = [NSSortDescriptor sortDescriptorWithKey:@"trackNumber" ascending:YES];
NSArray *albumNames = [songs valueForKeyPath:@"@distinctUnionOfObjects.albumName"];
NSMutableDictionary *groupedByAlbumAndSortedByTrack = [[NSMutableDictionary alloc] init];
for (NSString *album in albumNames) {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"albumName == %@",album];
NSArray *currentAlbumSongs = [songs filteredArrayUsingPredicate:predicate];
NSArray *currentAlbumSongsSortedByTrack = [currentAlbumSongs sortedArrayUsingDescriptors:@[byTrack]];
[groupedByAlbumAndSortedByTrack setObject:currentAlbumSongsSortedByTrack forKey:album];
}
return groupedByAlbumAndSortedByTrack;
}
@end
通过使用NSSortDescriptor进行排序和NSPredicate进行过滤,我们已经消除了大量的数组循环。
第一步是从我们使用KVC collectionOperator @distinctUnionOfObjects完成的歌曲数组中提取专辑名称。
然后我们遍历专辑名称数组,并将属于该专辑的所有歌曲添加到NSArray中。
上面给出的示例代码通常用于NSArray的排序和过滤。 快速浏览一下MPMediaItem类参考,可以看出apple已经为mediaItems的操作提供了很多方法。请看MPMediaPropertyPredicate。