使用UISearchBar按子字典中的键的值过滤字典

时间:2009-08-19 19:42:25

标签: iphone arrays dictionary filter

(注意:这是previous question的扩展名。)

我在为相当复杂的tableview实现SearchBar时遇到一些困难。 tableView有多个部分,两行文本和一个图像。所有数据都从plist加载,然后按“Name”键的值的首字母放入部分。 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开发”中的示例,但未能将其转换为我的情况。 因此,如果用户在搜索栏中键入“with 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";
  }
  );
}

为了澄清,我在视图中安装了我的searchBar,我只是无法使其正常运行。我现在正在使用一个名为 - (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 个答案:

答案 0 :(得分:1)

你的数据结构搞砸了你。

只需创建要显示的所有词典的单个数组,然后对其进行排序。将其分解为转租者只会让问题变得混乱。

所以,你有一个像这样的数组:

[[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中使用dicts和列表并不像在Python中那样好。

对NSObject进行子类化很简单。

答案 1 :(得分:0)

更新

看起来你在数组中有Letter键入的数组。

我可能会使用NSPredicate并过滤我感兴趣的任何键。

NSString *searchString = @"Nancy";

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(Name ==  %@)", Nancy];

NSArray *filteredArray = [[sectionedDictionaryByFirstLetter objectForKey:@"N"] filteredArrayUsingPredicate:predicate];

有关于谓词构造的指南。

还有其他方法,但这是首先想到的。


原始答案

您可以使用KVC方法:

valueForKeyPath:

获得你想要的东西。您应该阅读KVC苹果文档:

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

有许多方法可以“玩”字典/数组来做你想做的事情。不同的技术将具有不同的优势/优势。

答案 2 :(得分:0)

我的另一个想法是为“name”键创建一个包含所有值的数组。像这样:

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"
)

然后,在此阵列上运行过滤器。 最后,使用filteredArrayOfNames将项添加到具有匹配名称的新字典中。 这在概念上似乎在正确的轨道上吗?有更好的路线吗?

答案 3 :(得分:0)

好的,我终于回答了我自己的问题。这是下面的代码。我主要是在“开始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开发”网站here下载。这是“部分”的例子。