通过过滤另一个 NSDictionary 来获取一个 NSDictionary

Posted

技术标签:

【中文标题】通过过滤另一个 NSDictionary 来获取一个 NSDictionary【英文标题】:Getting an NSDictionary by filtering another NSDictionary 【发布时间】:2013-04-28 10:30:31 【问题描述】:

希望有人可以帮助我:

我使用NSDictionary 来填充UITableView。 它的模型类似于[key:userID => value:userName]。 tableView 只填充了用户名,但是当点击时,它必须发送相关的用户 ID。 当我想过滤UITable 时,问题就来了。我只找到了通过将字典转换为NSArray(使用谓词)来过滤字典的方法,但这让我失去了用户名和用户ID之间的关系。

一种解决方案是过滤初始 NSDictionary 以获得过滤后的 NSDictionary(仍然是关系键/值),但我不知道该怎么做。我只找到了获取数组的解决方案。

我该怎么做,或者有更好的解决方案吗?

【问题讨论】:

【参考方案1】:

有一个更好的解决方案,弗朗索瓦。 从您的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]];

然后,当您想要在用户选择单元格时传递用户 ID 时,在您的 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 数据源和委托方法。

【讨论】:

好吧,我明白你的意思了。我从错误的角度解决了这个问题,我被相同值的非问题所困扰。感谢您的帮助。 我很高兴能帮上忙。如果它解决了你的问题,也请投票:) 还没有足够的声誉来做这件事,但我会的:)【参考方案2】:

您可以执行以下操作来获取所选键(用户名)的值(用户 ID):

//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];
   

【讨论】:

【参考方案3】:

你正在使用 NSDictionary 来填充 UITableView,而这个 UITableView 只填充了你通过执行获得的用户名

[dictionary objectForKey@"userID"];

一个 NSDictionary 有两个函数 allkeys 和 allValues

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

这是一个并行数组,因此一个数组的索引与其关联的数组并行运行。

表格单元格的每个单元格也可以是一个自定义类,其中包含对其自己的 id 和用户名的引用,这将允许您只传递单元格并获取它的数据。

您可以在 NSDictionary 文档中阅读有关这些功能的信息

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

【讨论】:

我同意这两个 allKey 和 allValues 是并行的,但是当我在 allValues (userName) 数组上使用谓词时,我有一个过滤的名称数组,但没有更多相关的 ID。现在我解决了我的问题,但自定义类也是一个好主意。我可能会记住这一点以供进一步使用;)【参考方案4】:

我建议使用 NSDictionary 值创建 NSArray 或 NSMutableArray - 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 过滤

【讨论】:

以上是关于通过过滤另一个 NSDictionary 来获取一个 NSDictionary的主要内容,如果未能解决你的问题,请参考以下文章

快速过滤 [[NSDictionary]]

如何通过键过滤 NSArray:值,即在 NSDictionary

从另一个获取 NSDictionary 的 NSArray,其中包含原始键集的子集

NSPredicate 通过选择带有 Beginswith 的键来获取 NSDictionary 的值

带有数组的 nsdictionary nspredicate 过滤

获取与 NSDictionary 对象类型相关的错误