使用多个对象集合中的第一个项创建对象数组?

时间:2014-08-27 11:33:16

标签: ios arrays xcode sorting

我是Objective C和iOS编程的新手,并且已经徘徊在我脑海中的水域。任何帮助表示赞赏。

我在排序要在UITableView中使用的数组时遇到问题。基本上,我想查询一组相册,并根据用户设置按字母顺序或按日期(升序和降序)排序。首先我合成了一些全局数组,并且媒体查询了这些专辑:

@synthesize allSongs, arrayForTableView;
MPMediaQuery *songsQuery = [MPMediaQuery songsQuery];
[songsQuery setGroupingType: MPMediaGroupingAlbum];
arrayForTableView = [songsQuery collections];
allSongs = [songsQuery items];

到目前为止,这么好。相册按字母顺序排序,就像他们应该的那样。 allSongs数组用于其他地方的一些回放功能。所以现在,我添加了对设置的检测,并按照"年"进行排序。属性:

@synthesize allSongs, arrayForTableView;
MPMediaQuery *songsQuery = [MPMediaQuery songsQuery];
[songsQuery setGroupingType: MPMediaGroupingAlbum];
NSArray *allAlbums = [songsQuery collections];
allSongs = [songsQuery items];

if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"SortAlbumsMethod"] isEqualToString:@"0"]) {
    arrayForTableView = [songsQuery collections];
} else if ([[[NSUserDefaults standardUserDefaults] stringForKey:@"SortAlbumsMethod"] isEqualToString:@"1"]) {
    NSSortDescriptor *sortDescriptor;
    sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"year"
                                                 ascending:YES];
    NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
    arrayForTableView = [allAlbums sortedArrayUsingDescriptors:sortDescriptors];
} else {
    NSSortDescriptor *sortDescriptor;
    sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"year"
                                                 ascending:NO];
    NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
    arrayForTableView = [allAlbums sortedArrayUsingDescriptors:sortDescriptors];
}

这是我遇到问题的地方。以上内容不起作用,因为每个集合(专辑)都没有年份属性。如果我更换" allAlbums"用" allSongs,"代码正常运行。 除了,我现在每首歌都有一个条目。显示的标签信息仅与相册相关,导航基于AlbumPersistentID,所以一切都很好,我只是有太多重复的条目(看起来相同,因为歌曲名称没有显示)。

似乎显而易见的解决方案是创建一个数组,让我们称之为" albumRepresentatives"使用" allAlbums"中每个集合中的单个项目,并在排序描述符中使用它。每个项目实际上都是一首歌而不是专辑,但外观和功能仍然有效。理想情况下,我想比较每张专辑中的所有歌曲,选择一个具有最高"年份"属性并将其添加到" albumRepresentatives"。 B计划就是为每个专辑集合简单地将索引为0的歌曲。

问题是,实际上正在做,这在我的能力范围之外。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

一个选项可能是使用set,因为它们不存储重复的对象并使用数组的内容初始化它。您可能需要覆盖(可能添加到类别)isEqual来实现它。

第二个选项:

//Could be added as category to MPMediaItem for example
+(MPMediaItem*)latestSongInAlbum:(NSArray*)songsInAlbum
    MPMediaItem *latestSong = nil;
    for (MPMediaItem *song in songsInAlbum) {
     if(!latestSong) {
      latestSong = song;
     } else if([[latestSong valueForProperty: MPMediaItemPropertyReleaseDate] compare:
      [song valueForProperty: MPMediaItemPropertyReleaseDate]] == NSOrderedAscending]) {
     latestSong = song;
     }
    }
 return latestSong;
}

做类似于这个伪代码的事情:

NSMutableArray* latestSongFromeachAlbum = [[NSMutableArray alloc] initWithCapacity:[allAlbums count]];
for( album in allAlbums) {
 NSIndexSet* indexes = [allSongs indexesOfObjectsPassingTest:(^)(id obj, NSUInteger idx, BOOL *stop)) {
      return album == obj.album;
 }];
 NSArray* songsInAlbum = [allSongs objectsAtIndexes:indexes];

 MPMediaItem* latestSong = [ExtendedClass latestSongInAlbum:songsInAlbum];

 //now you have pair latestSong(you can use it's date) in album and the album. You can store as you prefer
 [latestSongFromeachAlbum addObject:latestSong];
}

希望它足够完整。