2011-08-29 31 views
15

Tôi sẽ biết cách lấy chỉ mục của một NSArray bằng cách sử dụng NSPredicate?Cách lấy chỉ mục của NSArray bằng NSPredicate?

NSArray *array = [NSArray arrayWithObjects: 
        @"New-York City", 
        @"Washington DC", 
        @"Los Angeles", 
        @"Detroit", 
        nil]; 

Mà loại phương pháp tôi nên sử dụng để có được các chỉ số của "Los Angles" bằng cách đưa ra chỉ một NSString
NB: @"Los An" hoặc @"geles" nên trả lại chỉ số tương tự ..

Trả lời

20

Sử dụng NSPredicate bạn có thể nhận được hàng loạt các chuỗi có chứa chuỗi tìm kiếm của bạn (có vẻ như không có built-in phương pháp để có được chỉ số yếu tố chỉ):

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] %@", searchString]; 
NSArray *filteredArray = [array filteredArrayUsingPredicate: predicate]; 

bạn có thể chỉ nhận được chỉ số sử dụng indexesOfObjectsPassingTest: metho d:

NSIndexSet *indexes = [array indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){ 
    NSString *s = (NSString*)obj; 
    NSRange range = [s rangeOfString: searchString]; 
    return range.location != NSNotFound; 
}]; 

Nếu bạn muốn chỉ nhận một phần tử có chứa chuỗi, bạn có thể sử dụng phương pháp tương tự indexOfObjectPassingTest:.

+0

nó nói range.origin không tồn tại ... – wagashi

+0

@wagashi, uh cảm ơn, tên thuộc tính sai. Hài hước bạn là người đầu tiên phát hiện lỗi - sau 7 tháng :) – Vladimir

+0

:) Nhân tiện, nó phải là "^ BOOL (id obj, NSUInteger idx, BOOL * stop)" – wagashi

21

Bạn sẽ có thể thực hiện việc này với các khối. Dưới đây là một đoạn (Tôi không có một trình biên dịch tiện dụng nên xin tha bất kỳ lỗi chính tả):

NSArray *array = [NSArray arrayWithObjects: 
       @"New-York City", 
       @"Washington DC", 
       @"Los Angeles", 
       @"Detroit", 
       nil]; 
NSString *matchCity = @"Los"; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF contains[cd] %@", matchCity]; 
NSUInteger index = [self.array indexOfObjectPassingTest:^(id obj, NSUInteger idx, BOOL *stop) { 
           return [predicate evaluateWithObject:obj]; 
        }]; 

Về cơ bản bạn có thể sử dụng indexOfObjectPassingTest: phương pháp. Điều này có một khối (mã sau "^") và trả về chỉ mục cho đối tượng đầu tiên khớp với vị từ của bạn (hoặc NSNotFound nếu không có kết quả phù hợp). Khối lặp đi lặp lại qua từng đối tượng trong mảng cho đến khi tìm thấy kết quả phù hợp (tại thời điểm đó nó trả về chỉ mục) hoặc không tìm thấy kết quả nào (tại thời điểm đó nó trả về NSNotFound). Dưới đây là một liên kết đến chặn các chương trình có thể giúp bạn hiểu được logic trong khối:

https://developer.apple.com/library/ios/featuredarticles/Short_Practical_Guide_Blocks/

+0

Câu trả lời tuyệt vời cảm ơn bạn –

1

tôi sẽ làm điều này ..

NSString * stringToCompare = @"geles"; 
int foundInIndex; 

for (int i=0; i<[array count]; i++){ 

    NSString * tryString = [[array objectAtIndex:i] description]; 

    if ([tryString rangeOfString:stringToCompare].location == NSNotFound) { 
     // no match 
    } else { 
     //match found 
     foundInIndex = i; 
    } 



}// end for loop 
+0

hãy để tôi thực hiện một số nhận xét: 1) nếu không có chuỗi kết hợp phần tử thì hàm foundInIndex của bạn sẽ vẫn chưa được khởi tạo và bạn không thể sử dụng nó. 2) bạn có thể có hiệu suất tốt hơn bằng cách sử dụng liệt kê nhanh hoặc liệt kê khối 3) không có ý nghĩa khi sử dụng phương pháp -description ở đây 4) lưu ý rằng mã của bạn sẽ tìm thấy phần tử cuối cùng trong mảng chứa chuỗi tìm kiếm – Vladimir

3

Tìm thấy một cách tiếp cận khác hữu ích cho tìm kiếm hơn phức tạp vì nó cho phép biến vị ngữ được sử dụng để tìm đối tượng rồi đối tượng để tìm chỉ mục:

-(NSIndexPath*) indexPathForSelectedCountry{ 
    NSUInteger indexToCountry = 0; 
    NSPredicate * predicate = [NSPredicate predicateWithFormat:@"isoCode = %@",self.selectedCountry.isoCode]; 
    NSArray * selectedObject = [self.countryList filteredArrayUsingPredicate:predicate]; 
    if (selectedObject){ 
     if (self.searchDisplayController.isActive){ 
      indexToCountry = [self.searchResults indexOfObject:selectedObject[0]]; 
     }else{ 
      indexToCountry = [self.countryList indexOfObject:selectedObject[0]]; 
     } 
    } 
    return [NSIndexPath indexPathForRow:indexToCountry inSection:0]; 
} 
0

Dựa trên @Louie answer, thay vì sử dụng cho vòng lặp tôi đã sử dụng khối liệt kê mà làm việc cho tôi.

Tôi đã làm điều này: -

NSString *stringToCompare = @"xyz"; 

[myArray enumerateObjectsUsingBlock:^(id *Obj, NSUInteger idx, BOOL * _Nonnull stop) { 
NSString * tryString = [[myArray objectAtIndex:idx] description]; 

    if ([tryString rangeOfString:stringToCompare].location == NSNotFound) { 

       // no match found 

     } else { 

       //match found and perform your operation. In my case i had removed array object at idx 

      } 
     }]; 
+0

đơn giản để tìm chỉ mục hơn thế này. – klefevre

Các vấn đề liên quan