Фильтрация словаря по значению ключа в словарях с помощью UISearchBar - PullRequest
0 голосов
/ 19 августа 2009

(Примечание: это расширение предыдущего вопроса .)

У меня возникли трудности с реализацией SearchBar для довольно сложного просмотра таблицы. TableView имеет несколько разделов, две строки текста и изображение. Все данные загружаются из списка, а затем помещаются в разделы по начальной букве значения ключа «Имя». NSLog возвращает следующее для моего основного словаря "sectionedDictionaryByFirstLetter":

sectionedDictionaryByFirstLetter:{
B = (
  {
    Name = "B...A Name Starting with B";
    Image = "ImageName1.png";
    Text = "Some Text";
  }
    );
C = (
  {
    Name = "C...A Name Starting with C";
    Image = "ImageName2.png";
    Text = "Some Text";
  }
    );
N = (
  {
    Name = "N1...A Name Starting with N";
    Image = "ImageName3.png";
    Text = "Some Text";
  },
  {
    Name = "N2...A Name Starting with N";
    Image = "ImageName4.png";
    Text = "Some Text";
  },
  {
    Name = "N3...A Name Starting with N";
    Image = "ImageName5.png";
    Text = "Some Text";
  }
  );
}

Я хочу отфильтровать под словари по значению ключа «Имя». Кто-нибудь может порекомендовать, как это сделать, или какие-то ресурсы для обучения, как? Я следовал примеру в «Начале разработки iPhone 3», но не смог перевести его в мою ситуацию. Поэтому, если пользователь вводит «с N» в строке поиска, я бы хотел, чтобы новый словарь отображался как:

    filteredSectionedDictionaryByFirstLetter:{
N = (
  {
    Name = "N1...A Name Starting with N";
    Image = "ImageName3.png";
    Text = "Some Text";
  },
  {
    Name = "N2...A Name Starting with N";
    Image = "ImageName4.png";
    Text = "Some Text";
  },
  {
    Name = "N3...A Name Starting with N";
    Image = "ImageName5.png";
    Text = "Some Text";
  }
  );
}

Просто чтобы уточнить, у меня установлена ​​панель поиска в представлении, у меня просто проблемы с ее функционированием. В настоящее время я играю с пользовательским методом - (void) handleSearchForTerm: (NSString *) searchTerm из примера в книге.

Спасибо за помощь!


Вот общая структура данных.

sectionedDictionaryByFirstLetter

Key   Value
B    Array of Dictionaries with Names beginning with B
      ....
C    Array of Dictionaries with Names beginning with C
      ...
N    Array of Dictionaries with Names beginning with N
     Item 1   Dictionary 1
     Item 2   Dictionary 2
     Item 3   Dictionary 3

          Dictionary 3
          {
          Name = "N3...A Name Starting with N";
          Image = "ImageName5.png";
          Text = "Some Text";
          }

Надеюсь, это поможет. Я все еще отчаянно ищу ответ на эту проблему.

По сути, есть первичный словарь, ключи которого - первые буквы элементов, которые он содержит. В каждой первой букве есть массив словарей, которые имеют значение для своего ключа «Имя», начинающегося с этой буквы.

Ответы [ 4 ]

1 голос
/ 24 августа 2009

Ваша структура данных портит вас.

Просто создайте один массив из всех словарей, которые вы хотите показать, и затем сохраните их отсортированными. Если разбить его на субаренды, это только запутает проблему.

Итак, у вас будет такой массив:

[[NSArray alloc] initWithObjects:
  [[NSDictionary alloc] initWithObjectsAndKeys: 
    @"a1", @"name", foo, @"bar", nil)],nil],
  [[NSDictionary alloc] initWithObjectsAndKeys: 
    @"b21", @"name", foo, @"bar", nil)],nil];

Тогда все просто. Просто отфильтруйте отсортированный массив по вводу в строке поиска. Вы даже можете хранить свои записи в базе данных CoreData, а затем объявить функцию, которая делает что-то вроде этого, чтобы получить их:

if (!self.wordList) {
  self.wordList = [self getWiordList]
} else {
  return self.wordList;
}

Кроме того, я бы посоветовал вам создать подкласс NSObject и использовать его массив вместо словарей, чтобы вы имели точечный доступ и синтаксис был приятным. Работа с диктовками и списками в Obj C не такая хорошая, как в Python.

Создать подкласс NSObject просто.

0 голосов
/ 25 августа 2009

Хорошо, я наконец-то ответил на свой вопрос. Вот код ниже. Я в основном следовал примеру поиска массива в «Начале разработки iPhone 3». Мне пришлось немного отредактировать его, чтобы он работал для моей проблемы. Вот мой код:

- (void)handleSearchForTerm:(NSString *)searchTerm
{   
NSMutableArray *sectionsToRemove = [[NSMutableArray alloc] init];
[self resetSearch];
for (NSString *key in self.keys)
{
    NSMutableArray *array = [self.copyOfSectionedDictionaryByFirstLetter valueForKey:key];
    NSMutableArray *toRemove = [[NSMutableArray alloc] init];
    for (NSDictionary *name in array)
    {
        if ([[name objectForKey:@"Name"] rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location == NSNotFound)
            [toRemove addObject:name];
    }

if ([array count] == [toRemove count])
    [sectionsToRemove addObject:key];
[array removeObjectsInArray:toRemove];
[toRemove release];
}

[self.keys removeObjectsInArray:sectionsToRemove];
[sectionsToRemove release];
[self.tableView reloadData]; 
}

Если вы хотите увидеть полный пример кода, чтобы увидеть, как это работает, вы можете загрузить его с сайта «Начало разработки iPhone 3» здесь . Это пример "разделов".

0 голосов
/ 24 августа 2009

Другая идея, которая у меня возникла, - создать массив всех значений для ключа «имя». Примерно так:

arrayOfNames:(
"B...A Name Starting with B",
"C...A Name Starting with C",
"N1...A Name Starting with N",
"N2...A Name Starting with N",
"N3...A Name Starting with N"
)

Затем запустите фильтр для этого массива. Наконец, используйте FilterArrayOfNames, чтобы добавить элементы в новый словарь с соответствующими именами. Кажется ли это концептуально на правильном пути? Есть ли лучший маршрут?

0 голосов
/ 19 августа 2009

Обновление

Похоже, у вас есть массивы с ключом в массиве в виде буквы.

Я бы, вероятно, использовал бы NSPredicate и фильтр для любого ключа, который меня интересовал.*

Существует руководство по построению предикатов.

Существуют и другие способы, но это первое, что приходит на ум.


Оригинальный ответ

ВыМожно использовать метод KVC:

valueForKeyPath:

Чтобы получить то, что вы хотите.Вы должны прочитать на KVC Apple Docs:

http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/

Есть много способов "играть" со словарями / массивами, чтобы делать то, что вы хотите.Разные техники будут иметь разные сильные стороны / преимущества.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...