【问题标题】:Creating array of objects with first items from multiple object collections?使用来自多个对象集合的第一项创建对象数组?
【发布时间】:2014-08-27 11:33:16
【问题描述】:

我是 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];
}

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

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

问题是实际上这超出了我的能力范围。任何帮助将不胜感激!

【问题讨论】:

    标签: ios arrays xcode sorting


    【解决方案1】:

    一个选项可能是使用 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];
    }
    

    希望它足够完整。

    【讨论】:

    • 谢谢。我最初尝试了一套,但它不起作用,因为同一张专辑中的多首歌曲不是真正的重复。它们似乎只是因为显示的属性在它们之间是通用的。你的第二个选项似乎仍然让我有点头晕,但我会开始玩这个。是否可以在返回时将每首“最新歌曲”添加到可变数组中?因为那个数组正是我需要的。感谢您的帮助!
    • 当然,您可以随意使用它:)。我个人会为此功能创建一个函数并从中返回数组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-12
    • 2018-10-28
    • 1970-01-01
    • 1970-01-01
    • 2019-02-07
    • 2021-03-30
    相关资源
    最近更新 更多