Obj-c - 如何将NSMutableArray的字符串转换为NSMutableDictionary,同时组合“like”键并对其Object值求和

时间:2017-09-20 10:53:53

标签: objective-c nsmutabledictionary

我是自学成才的目标-c,练习并尝试使用在线课程和堆栈溢出来学习。但是我陷入了僵局:

此数组由用户输入提交(选择一天并提供值)生成。我目前正在使用用户默认值 - 提供的值是动态的,这些都是示例:

NSMutableArray * arrayData;
arrayData = (NSMutableArray *) [[defaults objectForKey:@"uploadInputs"]mutableCopy];
    // Here is an example of arrayData         
    arrayData = "10/09/2017,05","12/09/2017,24","13/09/2017,05","13/09/2017,07","13/09/2017,02"

我想把它变成一个以日期为关键字和对象值的字典。当有一个类似的键我想要对对象中的值求和。所以期望的输出是:

{
    "10/09/2017" = 05;
    "12/09/2017" = 24;
    "13/09/2017" = 14;
}

但我目前得到的是:

{
  "10/09/2017" =     (
    05
);
  "12/09/2017" =     (
    24
);
  "13/09/2017" =     (
    05,
    07,
    02
);

} 

我做了什么:

  NSMutableDictionary *dictTest3 = [[NSMutableDictionary alloc] init];
    for (NSString *item in arrayData) {

        NSString *key = [[item componentsSeparatedByString:@","] firstObject];
        if(!dictTest3[key]){
           dictTest3[key] = [NSMutableArray new];
        }
        [dictTest3[key] addObject:[[item componentsSeparatedByString:@","] lastObject]];
    }
NSLog(@"dictTest3: %@ ",dictTest3);

我试图按照CRD 提供的一些步骤进行操作并简化代码 - 目前我正在努力解决的问题是现在总结为具有相同密钥而创建的NSMutableArray。

我可以在字典中定位NSMutableArray吗? 这样的事情是什么?

NSMutableArray *fuBar = ;
        NSInteger sum = 0;
        for (NSNumber *num in fuBar)
        {
            sum += [num intValue];
        }

2 个答案:

答案 0 :(得分:1)

到目前为止,您的代码在数组上迭代两次,将每个项目拆分两次,并丢弃在此迭代中不感兴趣的部分(日期/键,数字/值),创建两个中间数组。然后将这些数组合并到字典中。

您的第一个简单步骤是迭代一次,将每个项目分成关键字&值,并立即将它们添加到字典中。这意味着每个项目只被拆分一次,并且不需要中间数组。

它还可以帮助您解决如何处理重复键的剩余问题。如果您在字典中查找某个键并且没有相应的值,则会返回nil,使用此功能可以轻松组合您的值。使用NSStringNSDate个对象作为键并将NSNumber个对象作为值来生成字典:

  1. 将每个项目分成两部分
  2. 将值(秒)部分解析为整数
  3. 可选择将密钥(第一个)部分解析为日期或将其保留为字符串
  4. 查找词典中的键
  5. 如果键值不存在,请添加新的键/值对,将整数值包装为NSNumber对象,以便将其存储在词典中
  6. 如果密钥确实存在,请使用其匹配的NSNumber对象,解包为整数,将新值添加到其中,将总和包装为新的NSNumber对象并添加新的键/值对到您的字典 - 这将替换字典中现有的键/值对。
  7. HTH

答案 1 :(得分:0)

NSArray *arrayData = @[@"10/09/2017,05",
                       @"12/09/2017,24",
                       @"13/09/2017,05",
                       @"13/09/2017,07",
                       @"13/09/2017,02"];

NSMutableDictionary *finalDict = [[NSMutableDictionary alloc] init];

for (NSString *aString in arrayData)
{
    NSArray *components = [aString componentsSeparatedByString:@","];
    NSString *key = components[0]; //That's the date String

    NSNumber *number; //Number to set as value in the finalDict

    //We check before hand if there is already an entry
    number = [finalDict objectForKey:key];

    //Small trick: If there was no entry, then number is nil, and [number integerValue] gives 0 so after the execution number will be equals to components[1] converted into a NSNumber object. If not, it's simply added
    number = @([number integerValue] + [components[1] integerValue]);

    [finalDict setObject:number forKey:key];
}

NSLog(@"finalDict: %@", finalDict);

输出:

$> finalDict: {
    "10/09/2017" = 5;
    "12/09/2017" = 24;
    "13/09/2017" = 14;
}

注意,作为@CRD,我也想到了NSNumber而不是NSString的值。似乎更直觉。 我按照他的想法制定了一个类似的逻辑,它或多或少地具体执行了它的指令。