【问题标题】:NSMutableDictionary from NSMutableArray using KVC使用 KVC 的 NSMutableArray 中的 NSMutableDictionary
【发布时间】:2014-04-13 14:37:30
【问题描述】:

我有一个字典输入数组

myArray = (
    {
        name:"abc";
        time:"6:00";
    },
    {
        name:"xyz";
        time:"7:00";
    },
    .
    .
)

我想要这样的输出字典

myDictionary = {
    "6:00":(
        {
            name:"abc";
            time:"6:00";
        },
        .
        .
     )
     "7:00":(
        {
            name:"xyz";
            time:"7:00";
        },
        .
        .
     )
}

我尝试了什么:

我使用这一行成功获得了distinct times 的数组:

NSArray *arrTempKeys = [myArray valueForKeyPath:@"@distinctUnionOfObjects.Time"];

然后使用for loop中的谓词为arrTempKeys,得到所有具有相同time值的字典:

NSPredicate *pred = [NSPredicate predicateWithFormat:@"Date == %@",str];
NSArray *arrTemp = [myArray filteredArrayUsingPredicate:pred];

最后,我将这个arrTemp 分配为Key time 的对象,得到了想要的结果。


我想要什么:

我知道还有很多其他方法可以获得此输出。但我只想知道是否有任何单一的KVC 编码行或任何其他可用的最佳方式来做这件事。

【问题讨论】:

  • 类似问题在这里:stackoverflow.com/questions/22288481/… 和这里:stackoverflow.com/questions/20925537/…。还有一些关于“最佳”方法的讨论。
  • @MartinR:哎呀.. !!实际上我在问这个问题之前尝试过谷歌。但是当你不知道“类似问题的标题是什么”时,总是很难找到类似的问题。不过,如果您发现此问题不会为我们的社区增加任何价值,请将其标记为重复。

标签: ios iphone objective-c kvc


【解决方案1】:

NSDictionary 可以在 NSArray 和 KVC 的协助下做到这一点。

试试这个:

NSDictionary *myDictionary = [NSMutableDictionary dictionaryWithObjects:myArray
                                                                forKeys:[myArray valueForKey:@"time"];

这应该可以,因为 NSArray 的 -valueForKey: 版本会返回一个数组,该数组由每个键的元素返回的值组成。

警告:虽然上面的代码很简洁,似乎可以解决您的问题,但也并非没有一些陷阱。主要的一个是字典对于给定的键只能有一个值,这意味着如果数组中的两个或多个条目对于键@"time"具有相同的值,则只有其中一个(可能是最后一个)将在结果字典中表示。此外,如果任何条目缺少@"time" 的值,则该条目将以[NSNull null] 作为其键。如上,如果有两个或多个缺少time 值,则字典中将只表示一个。

编辑:仔细查看您的问题,我发现项目中的时间不一定不同,因此 Hot Licks 的回答可能对您更有意义。

【讨论】:

  • 聪明,但是:结果是字符串->字典的字典,而不是字符串->数组,按照要求。
  • @NikolaiRuhe 我不确定您对字符串的含义,但也许这只是语言差异。我认为你的观点是我的解决方案不适用于非不同的键 - 你得到一个每个键都有一个字典的字典,而不是每个键都有一个字典数组的字典。我完全同意。
【解决方案2】:

你想要的太多了。只写一个简单的循环。这将是最有效、最清晰、可能也是最可靠的解决方案:

NSMutableDictionary* myDict = [NSMutableDictionary dictionary];
for (NSDictionary* innerDict in myArray) {
    NSString* time = innerDict[@"time"];
    NSMutableArray* innerArray = myDict[time];
    if (innerArray == nil) {
        innerArray = [NSMutableArray array];
        [myDict setValue:innerArray forKey:time];
    }
    [innerArray addObject:innerDict];
}

【讨论】:

  • +1 同意这可能是非不同键的最佳解决方案。
【解决方案3】:

不,没有。 KVC 允许您导航关键路径,但它不会根据关键路径的内容以这种方式对数据进行整理。

【讨论】:

  • 感谢您的回答。我只想知道除了我使用的方法之外是否还有更好的方法,或者我的方法中是否需要任何优化。 :)
  • 在你有理由之前不要优化。你的代码是代码高效的,不一定是运行时高效的(你做了很多循环)。对此的任何更改都可能需要更多代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多