2015-09-07 3 views
0

В настоящее время я работаю с большим NSDictionary называется listOfAllWords, содержащее слово, и соответствующий счет, как, например:Фильтрация NSDictionary прогрессивно возрастает по мере один типов по значению

WORD : SCORE 
------------- 
hello : 100 
have : 90 
help : 80 
held : 70 
hot : 60 
hemp : 50 
... 

Моя цель состоит в том, как пользователь введите до 3-х предложений из списка, в соответствии с их оценкой .

Например, если пользователь только набирается «час», 3 рекомендации будут «привет», «есть» и помощь «в таком порядке. Тем не менее, если пользователь ввел» Хель . "уже, то рекомендации будут„привет“,„помощь“и„Ручной“

на основе подобной парадигмы фильтрации UITableViews, способ фильтровать бы сделать что-то вроде этого:

for (word* food in [listOfAllWords allKeys]){ 
     NSRange nameRange = [word rangeOfString:userInput options:NSCaseInsensitiveSearch]; 
     if(nameRange.location != NSNotFound 
     { 
      [filteredData addObject:word]; 
     } 
    } 

Однако проблема, с которой я сталкиваюсь, заключается в том, как включить фильтр для включения счет компонент, а также, чтобы он включал рекомендации, оцененные их оценками. Помощь очень ценится.

+0

Я бы предположил, что вы создаете объект со свойствами 'word' и' score'. Добавьте экземпляры этих объектов в свой массив 'filterData', а затем вы можете отсортировать массив по' score' убыванию и взять первые 3 элемента – Paulw11

+1

Это лучше решить с помощью дерева radix. (Но, конечно, это требует работы.) –

ответ

2

Самый простой подход может быть что-то вроде этого:

NSArray* matchingWords = [listOfAllWords.allKeys filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] %@", userInput]; 
NSArray* sortedMatches = [matchingWords sortedArrayUsingComparator:^NSComparisonResult (NSString* word1, NSString* word2) { 
    // Look up the score of each word and compare them. I put word2's score on the left to get descending (highest first) result. 
    return [listOfAllWords[word2] compare:listOfAllWords[word1]]; 
}]; 
// Limit to 3 matches 
if (sortedMatches.count > 3) 
    sortedMatches = [sortedMatches subarrayWithRange:NSMakeRange(0, 3)]; 

Это, безусловно, можно улучшить на скорости, но не беспокоить тех пор, пока вы не измерили реальную проблему производительности.

+0

Спасибо! Это великолепно работает, и почти не поражает производительность. Мое единственное продолжение - как улучшить «NSPredicate», чтобы вместо того, чтобы находить частично введенную строку в любой части 'matchWords', она найдет ее только в начале' matchWords'. Например, если я набрал только «он», результат должен начинаться только с «he-» (и не иметь таких предложений, как «the») Спасибо! – daspianist

+1

Замените 'CONTAINS' на' BEGINSWITH'. –

0

Вы можете создать второй словарь с ключами и значениями обмениваемых, как описаны в этом ответе: https://stackoverflow.com/a/19387825/364015

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

Смежные вопросы