NSSortDescriptor具有任意排序功能 [英] NSSortDescriptor with arbitrary sorting

查看:82
本文介绍了NSSortDescriptor具有任意排序功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法理解如何使用NSSortDescriptor进行任意排序。

I can't wrap my head around how to do arbitrary sorting with a NSSortDescriptor.

我想做这样的事情:

NSArray *sortAlgorithm = [NSArray arrayWithObjects:@"@", @"#", @"!", @"&", @"r", @"a", nil];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" 
                                                               ascending:YES 
                                                              comparator:
    ^(id obj1, id obj2) {
        NSComparisonResult comparisonResult;
        //Some code that uses sortAlgorithm.
        return comparisonResult;
    }
];

这会按键名称以便任何以 @ 开头的键,例如 @home ,将出现在以 r 开头的任何密钥之前,例如激进,再次出现在以 a 开头的任何密钥之前,例如任何

This would sort the objects by the key name so that any key that starts with @, e.g. @home, would come before any key that starts with r, e.g. radical, and that again would come before any key that starts with a, e.g. anything.

上面只是一个例子。关键是要启用完全任意的排序。

The above is just an example. The point is to enable completely arbitrary sorting.

这将用于NSFetchedResultsController。

This is to be used for a NSFetchedResultsController.

什么会的代码//使用sortAlgorithm 的一些代码看起来像?

What would the code for //Some code that uses sortAlgorithm look like?

编辑:

围绕我尝试实现sortDescriptor的代码,作为pr。 occulus'建议:

Code surrounding my attempt to implement a sortDescriptor, as pr. occulus' suggestion:

- (NSFetchedResultsController *)fetchedResultsController {
    if (__fetchedResultsController)
        return __fetchedResultsController;

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    fetchRequest.entity = [NSEntityDescription entityForName:@"Tag" inManagedObjectContext:self.temporaryManagedObjectContext];

    //NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO comparator:^(id obj1, id obj2) {

        NSArray *sortAlgorithm = [NSArray arrayWithObjects:@"#", @"!", @"@", @".", nil];

        NSString *obj1FirstChar = [(NSString *)obj1 substringToIndex:1];
        NSString *obj2FirstChar = [(NSString *)obj2 substringToIndex:1];
        int idx1 = [sortAlgorithm indexOfObject:obj1FirstChar];
        int idx2 = [sortAlgorithm indexOfObject:obj2FirstChar];

        if ( idx1 < idx2 )
            return NSOrderedAscending;
        else if ( idx1 > idx2 )
            return NSOrderedDescending;
        else
            return NSOrderedSame;
    }];

    fetchRequest.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
    fetchRequest.fetchBatchSize = 20;        

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.temporaryManagedObjectContext sectionNameKeyPath:nil cacheName:@"Tags"];

    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    [self.fetchedResultsController performFetch:nil];

    return __fetchedResultsController;
}

已注释掉的sortDescriptor可以工作。

The commented-out sortDescriptor works.

在实体Tag的对象上肯定有一个名为 name 的属性。但即使没有,这似乎也不是问题。 Xcode似乎甚至没有编译那行代码(sortDescriptor),这听起来很荒谬。断点工作正常,但不会破坏特定的代码行。

There is definitely a property called name on objects of entity "Tag". But even if there weren't, that doesn't seem to be the problem. Xcode doesn't seem to even be compiling that line of code (the sortDescriptor), which sounds ridiculous. Breakpoints are working just fine, but aren't breaking on that specific line of code.

推荐答案

你需要拔出第一个字符 obj1 obj2 字符串为 NSStrings ,找到他们的你的任意排序数组中的索引,然后比较位置。

You need to pull out the first characters of obj1 and obj2 strings as NSStrings, find their indexes in your arbitrary ordering array, then compare the positions.

这样的事情:(把这段代码放在你的 ^ block)

Something like this: (put this code in your ^ block)

NSString *obj1FirstChar = [(NSString *)obj1 substringToIndex:1];
NSString *obj2FirstChar = [(NSString *)obj2 substringToIndex:1];
int idx1 = [sortAlgorithm indexOfObject:obj1FirstChar];
int idx2 = [sortAlgorithm indexOfObject:obj2FirstChar];

// NOTE: we haven't dealt with the case where one of the
// chars wasn't found in the array of characters. A strategy
// for this would need to be decided.

if (idx1 == idx2) {
    return NSOrderedSame;
}
if (idx1 < idx2) {
    return NSOrderedAscending;
}
return NSOrderedDescending;

未经测试,可能需要稍加调整。注意大小写字符差异。

Not tested, may require a little tweaking. Watch out for upper/lower case character differences.

更新:使用自定义排序描述符和SQL支持的核心数据存储似乎存在问题。有关详细信息,请参阅此问题

UPDATE: It seems there are problems with using custom sort descriptors and SQL backed core data stores. Please see this question for more info.

这篇关于NSSortDescriptor具有任意排序功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆