2010-02-05 51 views
4

这让我感到困惑。我有一个做了这样的功能:sortUsingSelector不排序NSStrings阵列

void ListAllStoredLocations(NSString *SearchTerm){ 
NSMutableDictionary *item; 
NSString* filePath = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingString:@"/Preferences/yourprogram.plist"]; 

item = [[[NSMutableDictionary alloc] initWithContentsOfFile:filePath] mutableCopy]; 

NSMutableArray *ReadStoredArray = [item objectForKey:SearchTerm]; 
NSMutableArray *SortedArray = [[NSMutableArray alloc] init]; 
NSString *[email protected]""; 

for (int i = 0; i< [ReadStoredArray count]; i++){ 
    CurrentResult=(NSString *)[ReadStoredArray objectAtIndex:i]; 
    [SortedArray addObject:CurrentResult]; 
} 

[SortedArray sortUsingSelector:@selector(compare:)]; 

for (int i = 0; i< [SortedArray count]; i++){ 
    NSLog(@"%@",[SortedArray objectAtIndex:i]); 
} 


[item release]; 

}

指找到输出NSString的第一对这样的循环:

LOCATION1

LOCATION2

不是地点

LOCATION2

LOCATION3

LOCATION2

,我想输出是按字母顺序排列:

LOCATION1

LOCATION2

LOCATION2

LOCATION2

LOCATION3

不是一个位置

但是,无论怎样, “[SortedArray sortUsingSelector:@selector(比较:)]。”只是不排序数组。什么都没发生。

也许我在谈论这一切都是错误的,但是我在网上看到的每一个例子都将NSStrings这样排序 - 所以我不知道该怎么做。

我的结局,如果有更好的解决方案,那就输出最大重复条目的数量。我在想,分类将是朝这个方向迈出的一步。

真的,我正在寻找的是这样的输出:

LOCATION2

因为 “LOCATION2” 已在该名单上最重复。

任何帮助?

+0

查看'NSCountedSet'作为找到模式(最常见的元素)的替代方法。 – benzado 2010-02-05 08:11:40

回答

8

鉴于您的字符串数组是这样的:

NSMutableArray * array = [NSMutableArray array]; 
[array addObject:@"Location1"]; 
[array addObject:@"Location2"]; 
[array addObject:@"Not a location"]; 
[array addObject:@"Location2"]; 
[array addObject:@"Location3"]; 
[array addObject:@"Location2"]; 

NSLog(@"------------- original:"); 
for (id obj in array) NSLog(@"%@", obj); 

您可以这样排序是:

NSLog(@"------------- sorted:"); 
NSArray * sortedArray = 
    [array sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; 
for (id obj in sortedArray) NSLog(@"%@", obj); 

输出:

2010-02-06 00:24:14.915 x[23867:903] ------------- original: 
2010-02-06 00:24:14.917 x[23867:903] Location1 
2010-02-06 00:24:14.921 x[23867:903] Location2 
2010-02-06 00:24:14.922 x[23867:903] Not a location 
2010-02-06 00:24:14.922 x[23867:903] Location2 
2010-02-06 00:24:14.923 x[23867:903] Location3 
2010-02-06 00:24:14.924 x[23867:903] Location2 
2010-02-06 00:24:14.924 x[23867:903] ------------- sorted: 
2010-02-06 00:24:14.925 x[23867:903] Location1 
2010-02-06 00:24:14.926 x[23867:903] Location2 
2010-02-06 00:24:14.926 x[23867:903] Location2 
2010-02-06 00:24:14.927 x[23867:903] Location2 
2010-02-06 00:24:14.927 x[23867:903] Location3 
2010-02-06 00:24:14.928 x[23867:903] Not a location 

如果你想找到最出现的对象给出的原始数组:

NSCountedSet * set = [[NSCountedSet alloc] initWithArray:array]; 
for (id obj in set) NSLog(@"%d - %@", [set countForObject:obj], obj); 

int count = 0; 
int maxc = 0; 
id maxobj; 
for (id obj in set) 
{ 
    count = [set countForObject:obj]; 
    if (maxc < count) maxc = count, maxobj = obj; 
} 

NSLog(@"max is: %d - %@", maxc, maxobj); 

输出:

2010-02-06 00:39:46.310 x[24516:903] 1 - Location1 
2010-02-06 00:39:46.311 x[24516:903] 1 - Not a location 
2010-02-06 00:39:46.311 x[24516:903] 3 - Location2 
2010-02-06 00:39:46.312 x[24516:903] 1 - Location3 
2010-02-06 00:39:46.313 x[24516:903] max is: 3 - Location2 
+0

+1正是我该怎么做 – 2010-08-15 02:02:16

1

首先,你正在像疯了似的泄漏内存。学习规则:如果你创建一个对象(alloc/init或copy),那么你拥有它并且必须释放它。

item = [[[NSMutableDictionary alloc] initWithContentsOfFile:filePath] mutableCopy]; 

在该行中,您正在创建一个可变字典,然后创建它的可变副本,失去原始实例。您应该替换成:

item = [[NSDictionary alloc] initWithContentsOfFile:filePath]; 

你不会真的发生变异在你的代码字典,所以我让它成为NSDictionary的。

接下来,在此声明中的类型:

NSMutableArray *ReadStoredArray = [item objectForKey:SearchTerm]; 

不正确。即使字典是可变的,它的成员也不能保证。 (mutableCopy是一个浅拷贝)。因为你实际上并没有修改该阵列,让我们将该行更改为:

NSArray *ReadStoredArray = [item objectForKey:SearchTerm]; 

现在,如果你想从ReadStoredArray项目复制到SortedArray,你可以替换循环

[SortedArray addObjectsFromArray:ReadStoredArray]; 

但因为你正在做一个精确副本,你也可以只写

SortedArray = [ReadStoredArray mutableCopy]; 

但你似乎并不需要SortedArray是可变的,所以你可以只把这种其他形式,它返回一个新的有序数组,而不是地方排序一个可变数组:

SortedArray = [ReadStoredArray sortedArrayUsingSelector:@selector(compare:)]; 

所以,现在你的函数看起来是这样的:

void ListAllStoredLocations(NSString *SearchTerm) { 
    NSDictionary *item; 
    NSString* filePath = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingString:@"/Preferences/yourprogram.plist"]; 
    item = [[NSDictionary alloc] initWithContentsOfFile:filePath]; 

    NSArray *ReadStoredArray = [item objectForKey:SearchTerm]; 
    NSArray *SortedArray = [ReadStoredArray sortedArrayUsingSelector:@selector(compare:)]; 

    for (int i = 0; i< [SortedArray count]; i++){ 
     NSLog(@"%@",[SortedArray objectAtIndex:i]); 
    } 

    [item release]; 
} 

你不不需要释放ReadStoredArraySortedArray,因为你不拥有它们(在调用中没有alloc/init或copy)。

至于你的实际问题......代码没有明显的原因,为什么排序不起作用。抱歉!许多常见问题会引发异常,而不是无声的故障。

如果文件不存在或无法加载,initWithContentsOfFile:会引发异常。如果ReadStoredArray为零,则CurrentResult将为零,并且addObject:会引发异常。如果阵列中的对象没有响应compare:选择器,sortUsingSelector:会引发异常。如果SortedArray为零,则代码将默默失败,但它也不会打印输出。 (另外,因为它是零的alloc/init将不得不失败,这意味着你内存不足。)

除了内存泄漏和非传统风格(用大写字母开始你的变量名)没有什么明显错误与您的代码。缺了点什么。

+0

“至于你的实际问题......代码中没有明显的原因,为什么排序不起作用,对不起!” --- ACK dammit ....哈哈。非常感谢脚本上的指针。我完全不熟悉ObjC,它踢我的屁股。我会继续寻找。 – 2010-02-05 06:35:54

+0

不,我没有从我的方法中省略任何东西。 这仍然不排序阵列...这很奇怪。 – 2010-02-05 06:46:13

+0

我更新了我的答案(接近尾声),解释了几个常见的问题,因为您没有说出现异常,所以排除了这些问题。 – benzado 2010-02-05 18:00:57

0

我没有看到任何明显的会阻止你的数组排序,所以我会尝试使用自定义的myCompare:方法作为排序选择器而不是内置比较。这将允许您记录每个单独的比较,以便您知道每个对象都应该进行比较,并且它会返回正确的比较结果。

添加到您的文件(你的函数定义的上方),然后改变你的函数@selector排序(myCompare :):

@interface NSString (MyCompare) 

- (NSComparisonResult) myCompare: (NSString *) aString; 

@end 

@implementation NSString (MyCompare) 

- (NSComparisonResult) myCompare: (NSString *) aString 
{ 
    NSComparisonResult result; 

    result = [self compare: aString]; 

    NSLog(@"Compared %@ & %@, result: %d", self, aString, (int) result); 

    return result; 
} 

@end 
1

您可以使用API​​轻松数组排序:

[YourArrayObj sortUsingSelector:@selector(compare:)]; 

在这个语句之后,你只需打印你的数组对象就可以得到排序好的数组。

0

排序数组的一个小问题是,您必须查看数组是否正在排序过程中返回。如果你忽略捕获返回的数组,它可能看起来像数组没有被排序。它可能是,但只要它是,没有数组来捕捉它,它会再次消失。