从 NSDictionary 中按键获取具有特定值的对象

Posted

技术标签:

【中文标题】从 NSDictionary 中按键获取具有特定值的对象【英文标题】:Get object by key with certain value from NSDictionary 【发布时间】:2016-12-09 14:47:08 【问题描述】:

我有对象的 NSDictionary。 NSDictionary 由 json 组成(您可以在下面看到它)。我需要用 id 的名称填充我的表格视图。并且 id 可以重复。这意味着我可以有几个 id 等于 0 的“名称”。我应该从字典中按键获取具有特定值的名称。这是我的 NSDictionary:

    
        name = "smth1";
        id = 0;
    ,
        
        name = "smth2";
        id = 1;
    ,
        
        name = "smth3";
        id = 2;
    ,
        
        name = "smth4";
        id = 2;
    ,
   ...

例如,我想获取键“name”的值,其中 id 为 2。然后我将获取 name =“smth3”和 name =“smth4”。通常,我试图用嵌套数据填充我的表格视图组件。我怎样才能做到这一点?任何提示,想法。谢谢你。

【问题讨论】:

你有 NSDictionaryNSDictionarys,对吧? @ArtemNovichkov 不,我只有一个 NSDictionary。 但是nameid 是什么?是您模型的属性吗?什么包含你的NSDictionary 看起来你有一个字典数组。您也可以枚举所有这些对象并找出 dic[@"id"] isEqualToString @"2" @ArtemNovichkov 我有包含 json 的 NSDictionary(你可以在下面的问题中看到它)。 【参考方案1】:

实际上,您显示了一个字典数组,其中每个字典有 2 个键。

您可以使用 NSArray 函数 indexOfObjectPassingTest。该代码可能看起来像这样(从 NSArray 开始):

int idToFind = 2;
NSArray *dictArray = @[@@"name": @"smth1",
                         @"id": @(0),
                       
                       @@"name": @"smth2",
                         @"id": @(1),
                       
                       @@"name": @"smth3",
                         @"id": @(2)
                       ];


NSUInteger dictIndex = 
  [dictArray indexOfObjectPassingTest: ^BOOL(
    NSDictionary *dict, 
    NSUInteger idx, 
    BOOL *stop) 
       return [dict[@"id"] intValue] == idToFind;
  ];
if (dictIndex != NSNotFound) 
  NSLog(@"Found id %d with name %@", idToFind, dictArray[dictIndex][@"name"]);

编辑:

如果您需要匹配所有项目,那么您需要使用 NSArray 方法indexesOfObjectsPassingTest。这会找到数组中匹配的所有项目。

该代码如下所示:

int idToFind = 2;
NSArray *dictArray = @[@@"name": @"smth1",
                         @"id": @(0),
                       
                       @@"name": @"Fred",
                         @"id": @(2),
                       
                       @@"name": @"smth2",
                         @"id": @(1),
                       
                       @@"name": @"smth3",
                         @"id": @(2),
                       ];
NSIndexSet *dictIndexes;
dictIndexes = 
  [dictArray indexesOfObjectsPassingTest: ^BOOL(NSDictionary *dict,
    NSUInteger idx,
    BOOL *stop) 
  
    return [dict[@"id"] intValue] == idToFind;
  ];
 if (dictIndexes.count == 0) 
   NSLog(@"No matches found");
 
 [dictIndexes enumerateIndexesUsingBlock:^(NSUInteger index, 
   BOOL * _Nonnull stop) 
 
  NSLog(@"Found id=%@ with name \"%@\" at index %lu", 
    dictArray[index][@"id"], 
    dictArray[index][@"name"], 
    index);
 ];

上述两种方法都使用了带块的方法。该块包含您编写的代码,该代码为符合您所需搜索条件的项目返回 BOOL。

采用块的搜索/排序方法非常灵活,因为您可以提供任何想要进行匹配/比较的代码。

indexOfObjectPassingTest 方法在数组中搜索单个对象,并在找到第一个匹配项时停止。

相比之下,indexesOfObjectsPassingTest 函数将匹配多个项目。它返回一个NSIndexSet,一个用于索引到 NSArrays 的特殊类。

有一个函数 enumerateIndexesUsingBlock 为数组中指定的每个索引调用一个代码块。

我们还可以使用方法objectsAtIndexes 仅提取数组中结果索引集中列出的元素,然后使用for...in 循环遍历这些项目。该代码如下所示:

NSArray *filteredArray = [dictArray objectsAtIndexes: dictIndexes];
for (NSDictionary *aDict in filteredArray) 
  NSLog(@"Found id=%@ with name \"%@\"", aDict[@"id"], aDict[@"name"]);

请注意,这种事情在 Swift 中更简单、更简洁。我们可以在数组上使用filter 语句,并提供一个闭包来选择符合我们搜索条件的项目

【讨论】:

谢谢。你的回答奏效了。但它只显示了一个 id=0 的“名称”。我有几个 id=0 的名字。我更新了我的问题。请看一看。 哦。你没这么说。您可以重写上面的代码以使用 NSArray 函数 indexOfObjectsPassingTest,然后循环遍历生成的NSIndexSet

以上是关于从 NSDictionary 中按键获取具有特定值的对象的主要内容,如果未能解决你的问题,请参考以下文章

使用 NSDictionary 获取特定的 Json 数据

从具有特定值的表中获取列名

如何从对象数组中获取具有属性的列表,除非它包含具有特定值的另一个项目?

如何从元素中具有相同名称的 xml 文件中获取特定值?

从 NSDictionary 获取包含 NSNumber 布尔值的键列表,其中值为 @YES

从具有特定索引和过滤的 pandas df 中获取值