按键将NSArray分解为已排序的组

时间:2015-07-30 16:24:01

标签: ios xcode sorting nsarray nsdictionary

Noob在这里,可以使用一些帮助。

我有一张NSArray,里面装满了MPMediaItems(歌曲),我需要通过专辑来改组。我最终需要做的是:

1)按专辑分组曲目(未知专辑总数)。

2)按照曲目编号对专辑中的曲目进行排序。

3)返回一个包含所有曲目的新数组(按组随机分组,并按组中的数字顺序排列)。

我相信我知道如何通过一遍又一遍地遍历数组来做到这一点,但这看起来非常低效。我怀疑NSDictionary可能是更好的选择,但我甚至不知道从哪里开始。

非常感谢任何帮助!

麦克

1 个答案:

答案 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

相关问题