【问题标题】:Breaking NSArray into sorted groups by key按键将 NSArray 分解为排序组
【发布时间】:2015-07-30 16:24:01
【问题描述】:

这里是菜鸟,需要一些帮助。

我有一个 NSArray,里面装满了我需要按专辑随机播放的 MPMediaItems(歌曲)。我最终需要做什么:

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

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

3) 返回一个包含所有曲目的新数组(按组随机排列,仍然按组内的编号排序)。

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

任何帮助将不胜感激!

迈克

【问题讨论】:

    标签: ios xcode sorting nsarray nsdictionary


    【解决方案1】:

    尽管我没有使用过 MPMediaItems,但我可以解释一下 NSArray 的排序和过滤是多么简单。

    为了说明的目的,我创建了一个名为 Song 的虚构类,它可能与 MPMediaItem 不同。 Song 类有两个属性,分别称为 albumName 和 trackNumber。然后我们添加一个名为+ (NSDictionary *)songsGroupedByAlbumAndSortedByTrack:(NSArray *)songs 的类方法,它将接受一组 Song 对象并返回一个 NSDictionary。返回字典中的每个键都是专辑名称,对应的值是属于该专辑并按曲目编号排序的歌曲数组。

    @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 已经提供了很多用于操作 mediaItem 的方法。请查看MPMediaPropertyPredicate

    【讨论】:

    • 这太完美了!我能够从 [dictionary allKeys] 生成和随机化一个数组,然后遍历对象以完全实现我想要的。非常感谢! :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 1970-01-01
    • 1970-01-01
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多