1

Надежда кто-то может помочь мне с этим:Получение NSDictionary путем фильтрации другого NSDictionary

Я использую NSDictionary заполнить UITableView. Его модель похожа на [key:userID => value:userName]. TableView заполняется только именем пользователя, но при нажатии его необходимо отправить связанный с ним идентификатор пользователя. Проблема возникает, когда я хочу фильтровать UITable. Я только нашел способ фильтровать словарь, преобразовывая его в NSArray (используя Predicate), но это заставляет меня потерять связь между userNames и userID.

Решение состоит в том, чтобы отфильтровать начальный NSDictionary, чтобы получить отфильтрованный NSDictionary (с еще реляционным ключом/значением), но я не знаю, как это сделать. Я нашел решения для получения массивов.

Как я могу это сделать или есть лучшее решение для этого?

ответ

1

Существует гораздо лучшее решение, François. Создать из вашего NSDictionary (я буду называть его здесь myDictionary), NSArray, как это (объявить его в файле интерфейса):

NSArray *arrayForTableView; 

Затем, после того, как вы загрузили NSDictionary, выполните следующие действия:

arrayForTableView = [myDictionary allKeys]; // so you will have an array of all UserID's 

Теперь в вашем методе tableView: cellForRowAtIndexPath:, вы можете сделать это следующим образом:

cell.textLabel.text = [myDictionary objectForKey:[arraForTableView objectAtIndex:indexPath.row]]; 

И тогда, когда йо и будет хотеть передать идентификатор пользователя, когда пользователь выбирает ячейку, в вашем tableView: didSelectRowAtIndexPath: вы просто сделать это таким образом:

id userIDSelected = [arraForTableView objectAtIndex:indexPath.row]; 

Затем, когда вы хотите, чтобы фильтровать массив в соответствии с поиском, вы можете просто обновить ваш arrayForTableView, путем «сканирования» ваш NSDictionary таким образом:

NSString *typedString; 
NSMutableArray *arrayFiltered = [NSMutableArray array]; 
for (int i = 0; i < [[myDictionary allKeys] count]; i++) 
{ 
    if ([[myDictionary objectForKey:[[myDictionary allKeys] objectAtIndex:i]] rangeOfString:typedString].location != NSNotFound) 
    { 
     [arrayFiltered addObject:[[myDictionary allKeys] objectAtIndex:i]]; 
    } 
} 

arrayForTableView = arrayFiltered; 

Таким образом, вы даже не нужно изменить UITableView DataSource и делегировать методы.

+0

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

+0

Я рад, что помог. Пожалуйста, проголосуйте также, если он решит вашу проблему :) –

+0

Недостаточно репутации, чтобы сделать это, но я буду :) –

0

Вы можете сделать следующее, чтобы получить значение (USERID) для выбранного ключа (имя пользователя):

//iterate through whole dictionary 
for(id key in yourNSDictionary) 
{ 
    // if key is the userName clicked 
    if([key isEqualToString:selectedUserName]) 
    { 
     //userID for clicked userName 
     int userID = [yourNSDictionary objectForKey:@selectedUserName]; 
    } 
} 
0

вы используете NSDictionary для заполнения в UITableView и это UITableView заполняется только с именем пользователя, которое вы получите делая

[dictionary [email protected]"userID"]; 

NSDictionary имеет две функции AllKeys и allValues ​​

NSArray* allUserID = [dictionary allKeys]; 
NSArray* allUserNames = [dictionary allValues]; 

это параллельные массивы, так что индекс одного массива выполняется параллельно с его связанным массивом.

Каждая ячейка ячейки таблицы также может быть специальным классом, который содержит ссылку на свой собственный идентификатор и имя пользователя, это позволит вам передавать только ячейку и иметь ее данные.

вы можете прочитать об этих функциях в документации NSDictionary

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSDictionary_Class/Reference/Reference.html

+0

Я согласен, что два allKey и allValues параллельно, но когда я использовал предикат в массиве allValues ​​(userName), у меня был отфильтрованный массив имен, но больше не было связанных идентификаторов. Теперь я решил свою проблему, но пользовательский класс тоже неплохая идея. Я, вероятно, буду помнить об этом для дальнейшего использования;) –

0

я бы рекомендовал создающее NSArray или NSMutableArray со значениями NSDictionary - UITableViews предназначены для движимых массивов, где индекс массива совпадает с номер строки. Затем вы можете легко создать настраиваемый фильтр для массива словарей, который учитывает вашу структуру данных. Ваш код может включать в себя часть этого образца код:

NSString *idKey = @"userId"; 
NSString *nameKey = @"userName"; 
NSArray *arr = @[ 
     @{ 
       idKey : @(24), 
       nameKey : @"Oil Can Henry" 
     }, 
     @{ 
       idKey : @(32), 
       nameKey : @"Doctor Eggman" 
     }, 
     @{ 
       idKey : @(523), 
       nameKey : @"Sparticus" 
     }, 
]; 
NSString *searchTerm = @"Spar"; 
NSArray *newArray = [arr filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { 
    return [evaluatedObject[nameKey] hasPrefix:searchTerm]; 
}]]; 

Преимуществе:

  • единой структура данных для представления всех данных
  • присущих детерминированного заказ
  • поддержки фильтрации NSPredicate
Смежные вопросы