2010-02-05 35 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

排序數組的一個小問題是,您必須查看數組是否正在排序過程中返回。如果你忽略捕獲返回的數組,它可能看起來像數組沒有被排序。它可能是,但只要它是,沒有數組來捕捉它,它會再次消失。