Поиск NSArray объектов NSDictionary - PullRequest
15 голосов
/ 01 мая 2011

У меня есть массив контактов, где каждый контакт представляет собой словарь.

Каждый контакт имеет ключ "contact_type", который является NSNumber.Тип контакта в основном представляет собой контакт Facebook, LinkedIn или Mail и т. Д. У меня есть поисковый массив, который содержит только NSNumber для contact_type.

Я хочу создать временный массив контактов, который я хочу найти, используя мой массив поиска.

Я столкнулся с проблемой использования NSPredicate для создания массива искомых контактов.Кто-нибудь может подсказать мне, как это сделать?

Ответы [ 3 ]

37 голосов
/ 01 мая 2011
NSArray *contacts = ...; //your array of NSDictionary objects
NSPredicate *filter = [NSPredicate predicateWithFormat:@"contact_type = 42"];

NSArray *filteredContacts = [contacts filteredArrayUsingPredicate:filter];

После этого filteredContacts будет содержать только контакты, для которых contact_type равно 42.

Если вам нужно найти более одного вида contact_type, просто используйте OR в предикате:

filter = [NSPredicate predicateWithFormat:@"contact_type = 42 OR contact_type = 23"];
1 голос
/ 15 декабря 2015

Это решение отлично работает для меня.

// NSDictionary Format

{
 18=(
     {
        content="Great Avijit",
        id=abc
     }
 ),
13=(
     {
        content="Stack Overflow is cool",
        id=abc
      }
 ),
} 

// Шаг 1

 -(void)filterContentForSearchText:(NSString *)searchText
   {
        [self.filterResultArray removeAllObjects];

         NSPredicate *namePredicate = [NSPredicate predicateWithFormat:@"(content contains[cd] %@)", searchText];//from_user.name
           //other

         for (NSMutableDictionary *key in self.messageAll) {

             NSArray *array=[self.messageAll objectForKey:key];
              array=[array filteredArrayUsingPredicate:namePredicate];

             if ([array count]==0) {
                     [self.filterResultArray removeObject:key];
             }
             else{

               if ([self.filterResultArray containsObject:key]) {

                }
                else{
                      [self.filterResultArray addObject:key];
                }

            }

      }


      //Reload table view
      [self.tableView reloadData];

  }

// Шаг 2: numberOfRowsInSection

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {


    if (self.searchController.active && ![self.searchController.searchBar.text isEqualToString:@""]) {
        return [self.filterResultArray count];
    }else{
        return [keyArray count];//keyArray hold all key of original dict
    }

}

// Шаг 3: в методе cellForRowAtIndexPath

 NSString *key = [self.filterResultArray objectAtIndex:indexPath.row];
  NSDictionary *dictionary = [[self.messageAll objectForKey:key] lastObject];//self.messageAll is original dict
0 голосов
/ 09 октября 2016

Ответ Дейва выше идеален, я просто добавляю сюда то, что я узнал после трех часов ночного сна.

Когда вы пытаетесь найти строковые значения в словаре массива, вам нужно использовать предикат примерно так:

NSPredicate *filter = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"Title CONTAINS[cd] '%@' OR Description CONTAINS[cd] '%@'", searchText, searchText]];

Не забудьте обернуть ваши значения в '', это было единственное, что стоило мне все время. Вот моя последняя функция поиска

-(void)searchTerm : (NSString*)searchText {
    if (searchText!=nil && searchText.length) {
        NSPredicate *filter = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"Title CONTAINS[cd] '%@' OR Description CONTAINS[cd] '%@'", searchText, searchText]];
        self.reasonDetailArray = [self.unfilteredReasonDetailArray filteredArrayUsingPredicate:filter];
    }else{
        self.reasonDetailArray = self.unfilteredReasonDetailArray;
    }
    [self.tableView reloadData];
}
...