2012-04-30 2 views
5

Tôi có một trường có đầy đủ các id từ một bên thứ ba. Các id là các số nhưng được ghi vào db dưới dạng một chuỗi.NSSortDescriptor sắp xếp một trường chuỗi dưới dạng một số với khối so sánh không hoạt động

Tôi muốn sắp xếp tìm nạp được sắp xếp theo id này trên giá trị của số nguyên. Vì vậy, tôi đang thêm NSSortDescriptor này vào số NSFetchRequest.

NSNumberFormatter *numFormatter = [[NSNumberFormatter alloc] init]; 
[numFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; 
NSSortDescriptor *sortBy = [[NSSortDescriptor alloc] initWithKey:@"someId" ascending:YES comparator:^(id a, id b) { 
    return [[numFormatter numberFromString:a] compare:[numFormatter numberFromString:b]]; 
}]; 
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortBy]]; 

Nhưng tôi nhận được kết quả như sau. Chúng vẫn được sắp xếp dưới dạng một chuỗi, theo thứ tự bảng chữ cái.

730275292 
73900038 
730172867 
7350727 
830138437 
835164 
837287901 
8338804 
930274 
9324376 

Tôi không hiểu gì về việc sử dụng khối so sánh này?

EDIT 01 tháng 5 2012 09:20 EST

Để kiểm tra xem khối so sánh đang được sử dụng, tôi đã thử sau để phân loại dựa vào độ dài của lĩnh vực này.

NSSortDescriptor *sortBy = [[NSSortDescriptor alloc] initWithKey:@"fbId" ascending:YES comparator:^(id a, id b) { 
    if ([a length] < [b length]) { 
     return NSOrderedAscending; 
    } else if ([a length] > [b length]) { 
     return NSOrderedDescending; 
    } else { 
     return NSOrderedSame; 
    } 
}]; 
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortBy]]; 

Tôi vẫn nhận được kết quả được sắp xếp theo thứ tự bảng chữ cái! Vì vậy, điều này làm cho tôi nghĩ rằng khối so sánh thậm chí không được sử dụng.

716164250 
726354466 
73900038 
739600038 
7450727 
810138437 
801164 
801375346 
8213997 
+0

numFormatter trả về gì? Int? Chuỗi? –

+0

NSNumberFormatter * numFormatter = [[Cấp phát NSNumberFormatter] init]; [numFormatter setNumberStyle: NSNumberFormatterDecimalStyle]; –

+0

Bạn đã thử thiết lập một điểm ngắt trong khối so sánh để xem nó có đang được gọi không? Nếu nó được gọi thì bạn có thể chắc chắn đó là mã khối sai. –

Trả lời

1

Tôi không sử dụng NSFetchRequest nên tôi không thể nhận xét cụ thể, nhưng có vẻ như nó không liên quan gì đến nó. Mã bạn sử dụng trong khối so sánh của bạn chỉ là tốt. Tôi thiết lập một loạt các con số chính xác mà bạn hiển thị và sau đó sắp xếp chúng bằng mã của bạn và tất cả mọi thứ đã làm việc ra tốt đẹp:

NSArray *array = [NSArray arrayWithObjects:@"730275292", 
         @"73900038", 
         @"730172867", 
         @"7350727", 
         @"830138437", 
         @"835164", 
         @"837287901", 
         @"8338804", 
         @"930274", 
         @"9324376", nil]; 
    NSNumberFormatter *numFormatter = [[NSNumberFormatter alloc] init]; 
    [numFormatter setNumberStyle:NSNumberFormatterDecimalStyle]; 
    NSArray *sArray = [array sortedArrayUsingComparator:^(id a, id b) { 
     return [[numFormatter numberFromString:a] compare:[numFormatter numberFromString:b]]; 
    }]; 
    NSLog(@"%@",sArray); 

Khi mã trên chạy, tôi nhận được một bản ghi của:

(
    835164, 
    930274, 
    7350727, 
    8338804, 
    9324376, 
    73900038, 
    730172867, 
    730275292, 
    830138437, 
    837287901 
) 

tôi tin rằng đây là thứ tự bạn đang tìm kiếm. Bạn có thể xem xét việc lấy kết quả của yêu cầu tìm nạp của bạn và sắp xếp chúng trong một mảng sau khi bạn nhận được chúng. Tôi nghi ngờ nó quan trọng cho dù một mảng hiện các phân loại hoặc yêu cầu lấy không phân loại. Nhiều khả năng không có hiệu suất của việc sử dụng một trong những khác.

Nếu bạn vẫn muốn NSFetchRequest thực hiện việc sắp xếp, thì có thể có thứ gì đó bị thiếu của bạn để làm cho nó sắp xếp đúng cách. Thành thật mà nói, tôi không chắc chắn vì tôi đã không sử dụng nó.

CẬP NHẬT

Xem nhanh tài liệu NSFetchRequest, tôi thấy rằng có một số tham số ảnh hưởng đến sắp xếp. Ví dụ, trong các tài liệu cho resultType nó mang lại thông điệp này:

Bạn sử dụng setResultType: để thiết lập kiểu thể hiện của đối tượng trở từ thực hiện theo yêu cầu-cho giá trị có thể, xem Nếu bạn “NSFetchRequestResultType.” đặt giá trị thành NSManagedObjectIDResultType, điều này sẽ giảm hạng bất kỳ thứ tự sắp xếp nào thành các đề xuất “nỗ lực tốt nhất” nếu bạn không bao gồm giá trị thuộc tính trong yêu cầu .

Vì vậy, có vẻ như kiểu trả về có thể ảnh hưởng đến việc sắp xếp của bạn.

+1

Câu trả lời hàng đầu cho http://stackoverflow.com/questions/4789782/nsfetchedresultscontroller-custom-sort-not-getting-called cho thấy rằng một số khối so sánh khách quan-c không thể được "biên dịch" thành SQL và đề xuất về cơ bản những gì bạn đề xuất. Ehh, workaround hợp lý, nhưng tôi rất thích nhận được câu trả lời thực sự của lý do tại sao khối so sánh không hoạt động. Ngoài ra, thường thì đây không phải là giải pháp vì điều quan trọng là có dữ liệu trong NSFetchResultsController (ví dụ: khi bạn đang sử dụng nó trong một TableView và tận dụng NSFetchedResultsControllerDelegate để cập nhật cho giao diện người dùng). –

+0

Vâng, tôi chỉ cập nhật câu trả lời. Tôi đã tìm kiếm về 'sắp xếp' trong NSFetchRequest và thấy rằng 'resultType' có thể ảnh hưởng đến việc sắp xếp. Bạn có thể muốn nhìn vào đó. Thật không may, tôi sử dụng SQLite trực tiếp, thay vì sử dụng Core Data, vì vậy đây là mức độ hiểu biết của tôi. –

+1

Câu trả lời thực là chính xác những gì bạn đã chú ý-- các yêu cầu tìm nạp không thể chuyển đổi các khối so sánh thành SQL, do đó các bộ mô tả sắp xếp dựa vào các khối đó không hoạt động với các yêu cầu tìm nạp dữ liệu lõi. Liên kết tài liệu trong câu trả lời đó giải thích chi tiết hơn. –

11

Hãy thử cái này!

[NSSortDescriptor sortDescriptorWithKey:@"name" 
ascending:YES 
selector:@selector(localizedStandardCompare:)] 
+2

Điều này đã không sắp xếp tên nếu kiểu dữ liệu tên là đôi – coolcool1994

+0

Cảm ơn! Cuối cùng là một phương pháp thực sự hoạt động. – turingtested