如何按字母顺序对NSArray进行排序?

382

如何将由 [UIFont familyNames] 填充的数组按字母顺序排序?

7个回答

735
最简单的方法是提供一个排序选择器(详见苹果文档)。 Objective-C
sortedArray = [anArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

Swift

let descriptor: NSSortDescriptor = NSSortDescriptor(key: "YourKey", ascending: true, selector: "localizedCaseInsensitiveCompare:")
let sortedResults: NSArray = temparray.sortedArrayUsingDescriptors([descriptor])

苹果提供了几种字母排序的选择器:

  • compare:
  • caseInsensitiveCompare:
  • localizedCompare:
  • localizedCaseInsensitiveCompare:
  • localizedStandardCompare:

Swift

var students = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]
students.sort()
print(students)
// Prints "["Abena", "Akosua", "Kofi", "Kweku", "Peter"]"

参考资料


5
文档链接已过期,代码示例并不足以对数组进行排序。需要以某种方式定义 localizedCaseInsensitiveCompare:。 - M. Ryan
34
我更新了链接。感谢你指出来。localizedCaseInsensitiveCompare: 是 NSString 的一个方法,足以对字符串数组进行排序。 - Thomas Zoechling
1
这个方法可以轻松地应用于包含任何自定义对象(而不仅仅是NSString)的数组。您只需要确保数组中的所有对象都实现了选择器指定的消息。然后在此消息内,您只需调用NSString compare来比较您想要比较的对象属性。 - lgdev
这样简单的事情不应该如此复杂。 - Dmitry

281

这里提供的其他答案提到了使用@selector(localizedCaseInsensitiveCompare:)。对于一个NSString数组,这很有效,但如果你想将其扩展到另一种类型的对象,并根据名称属性对这些对象进行排序,那么你应该这样做:

NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
sortedArray=[anArray sortedArrayUsingDescriptors:@[sort]];

您的对象将根据这些对象的名称属性进行排序。

如果您希望排序不区分大小写,您需要像这样设置描述符

NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:)];

14
+1,谢谢。有趣的是,这种用法比被接受的答案更为常见。 - Vinay W
4
此程序先将大写字母排序,然后再排小写字母。 - HarshIT
+1,排序描述符连同选择器正是我想要的,其他回答都没有这个。非常感谢。 - Ganesh Somani
1
当我尝试用这种方式对字符串数组进行排序时,出现了错误,因为“name”不是有效的键。使用NSSortDescriptor按字母顺序排序字符串时,我应该使用哪个键? - temporary_user_name

29

使用NSNumericSearch等方式进行NSString列表排序的更强大方法:

NSArray *sortedArrayOfString = [arrayOfString sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
            return [(NSString *)obj1 compare:(NSString *)obj2 options:NSNumericSearch];
        }];

结合SortDescriptor,这将会得到类似于:

NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES comparator:^NSComparisonResult(id obj1, id obj2) {
        return [(NSString *)obj1 compare:(NSString *)obj2 options:NSNumericSearch];
    }];
NSArray *sortedArray = [anArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];

12

另一种简单的对字符串数组进行排序的方法是使用NSString description属性,方法如下:

NSSortDescriptor *valueDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES];
arrayOfSortedStrings = [arrayOfNotSortedStrings sortedArrayUsingDescriptors:@[valueDescriptor]];

1
这似乎有点无用;没有理由以这种方式对字符串进行排序(而且这样做可能会影响性能),对于其他对象来说,它的描述属性很少用于排序。 - mah

10

使用以下代码按字母顺序排序:

    NSArray *unsortedStrings = @[@"Verdana", @"MS San Serif", @"Times New Roman",@"Chalkduster",@"Impact"];

    NSArray *sortedStrings =
    [unsortedStrings sortedArrayUsingSelector:@selector(compare:)];

    NSLog(@"Unsorted Array : %@",unsortedStrings);        
    NSLog(@"Sorted Array : %@",sortedStrings);

以下是控制台日志:

2015-04-02 16:17:50.614 ToDoList[2133:100512] Unsorted Array : (
    Verdana,
    "MS San Serif",
    "Times New Roman",
    Chalkduster,
    Impact
)

2015-04-02 16:17:50.615 ToDoList[2133:100512] Sorted Array : (
    Chalkduster,
    Impact,
    "MS San Serif",
    "Times New Roman",
    Verdana
)

3

这个问题已经有了很好的答案,但我会添加我的答案,更加具体。

在英语中,通常当我们按字母顺序排列时,忽略短语开头的单词“the”。因此,“The United States”将按“U”而不是“T”排序。

这个工具可以为您完成这个操作。

最好将它们放在类别中。

// Sort an array of NSStrings alphabetically, ignoring the word "the" at the beginning of a string.

-(NSArray*) sortArrayAlphabeticallyIgnoringThes:(NSArray*) unsortedArray {

    NSArray * sortedArray = [unsortedArray sortedArrayUsingComparator:^NSComparisonResult(NSString* a, NSString* b) {

        //find the strings that will actually be compared for alphabetical ordering
        NSString* firstStringToCompare = [self stringByRemovingPrecedingThe:a];
        NSString* secondStringToCompare = [self stringByRemovingPrecedingThe:b];

        return [firstStringToCompare compare:secondStringToCompare];
    }];
    return sortedArray;
}

// Remove "the"s, also removes preceding white spaces that are left as a result. Assumes no preceding whitespaces to start with. nb: Trailing white spaces will be deleted too.

-(NSString*) stringByRemovingPrecedingThe:(NSString*) originalString {
    NSString* result;
    if ([[originalString substringToIndex:3].lowercaseString isEqualToString:@"the"]) {
        result = [[originalString substringFromIndex:3] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    }
    else {
        result = originalString;
    }
    return result;
}

1
我刚刚看了这个,几年后才发现它还应该包括 "a" 和 "an"。这些很容易添加。 - narco

1
-(IBAction)SegmentbtnCLK:(id)sender
{ [self sortArryofDictionary];
    [self.objtable reloadData];}
-(void)sortArryofDictionary
{ NSSortDescriptor *sorter;
    switch (sortcontrol.selectedSegmentIndex)
    {case 0:
            sorter=[[NSSortDescriptor alloc]initWithKey:@"Name" ascending:YES];
            break;
        case 1:
            sorter=[[NSSortDescriptor alloc]initWithKey:@"Age" ascending:YES];
            default:
            break; }
    NSArray *sortdiscriptor=[[NSArray alloc]initWithObjects:sorter, nil];
    [arr sortUsingDescriptors:sortdiscriptor];
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接