繁体   English   中英

从NSArray创建结构化的NSDictionary

[英]Create a structured NSDictionary from a NSArray

我需要从NSArray开始,创建具有分组密钥的结构化NSDictionary
这是一个例子:

[
    {
        section = section1,
        category = category1,
        date = 2011-12-01,
        key1 = foo,
        key2 = bar
    },
    {
        section = section1,
        category = category2,
        date = 2011-12-01,
        key1 = foo,
        key2 = bar
    },
    {
        section = section1,
        category = category2,
        date = 2011-12-03
        key1 = foo,
        key2 = bar
    },
    {
        section = section2,
        category = category1,
        date = 2011-12-03
        key1 = foo,
        key2 = bar
    }
]  

结果应该是这样的NSDictionary (我没有检查这些值是否正确,我只是想给出个主意):

[
    section1 = {
        category1 = {
            2011-12-01 = 
                [{
                    key1 = foo;
                    key2 = bar;
                },
                {
                    key1 = foo;
                    key2 = bar;
                }
                ]
            }
        },
        category2 = {
            2011-12-01 =
                [{
                    key1 = foo;
                    key2 = bar;
                }],
        }
    },
    section2 = {
        category1 = {
            2011-12-01 =
                [{
                    key1 = foo;
                    key2 = bar;
                }]
        }
    }
]

我可以使用NSPredicate或键值编码来实现这一点,并且避免很多循环吗?

我建议的解决方案

NSMutableDictionary *sectionEmpty = [NSMutableDictionary dictionary];
NSArray *values = [records allValues];

NSArray *sections = [[records allValues] valueForKeyPath:@"@distinctUnionOfObjects.section"];

for(NSString *section in sections) {
    // Find records for section
    NSArray *sectionRecords = [values filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"section == %@",section]];

    // Find unique categories
    NSArray *categorys = [sectionRecords valueForKeyPath:@"@distinctUnionOfObjects.category"];

    // Loop through categories
    for (NSString *category in categorys) {

        // Creating temporary record
        NSMutableDictionary *empty = [NSMutableDictionary dictionary];

        // Find records for category
        NSArray *categoryRecords = [sectionRecords filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"category == %@",category]];

        // Find unique dates
        NSArray *dates = [categoryRecords valueForKeyPath:@"@distinctUnionOfObjects.date"];

        // Loop through dates
        for (NSString *date in dates) {

            // Creating temporary record
            NSMutableDictionary *emptyDate = [NSMutableDictionary dictionary];

            // Find records for dates
            NSArray *dateRecords = [categoryRecords filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"date == %@",date]];

            // Split date
            NSString *dateString = [[date componentsSeparatedByString:@" "] objectAtIndex:0];

            // Check if date exist in temporary record
            if(![[emptyDate allKeys] containsObject:dateString]){
                [emptyDate setObject:[NSMutableArray array] forKey:dateString];
            }

            // Set date records for date key
            [[emptyDate objectForKey:dateString] addObject:dateRecords];

            // Set date for category
            [empty setObject:emptyDate forKey:category];
        }

        // Set category for section
        [sectionEmpty setObject:empty forKey:section];
    }

}

看来,实现所需目标的唯一方法是一系列嵌套的for循环(对于每个级别:部分,类别,日期)。 在最内层的循环中,您将创建一个复杂的谓词,如下所示:

NSPredicate *predicate = [NSPredicate predicateWithFormat:
                          @"section = %@ AND category = %@ AND date = %@",
                          section, category, date];

然后,您将滤除输入数组,并仅使用key1key2构造新的字典数组。 您将此日期数组添加到给定日期的类别字典,然后将类别字典添加到给定类别的输出字典。 我看不到任何更简单的方法。

NSArray *input = [records allValues];
NSMutableDictionary *output = [NSMutableDictionary dictionary];


NSArray *sections = [NSArray valueForKeyPath:@"@distinctUnionOfObjects.section"];
NSArray *categories = [NSArray valueForKeyPath:@"@distinctUnionOfObjects.category"];
NSArray *dates = [NSArray valueForKeyPath:@"@distinctUnionOfObjects.date"];

NSPredicate *predicate;
for (NSString *section in sections) {
    NSMutableDictionary *categoriesDictionary = [NSMutableDictionary dictionary];

    for (NSString *category in categories) {
        NSMutableArray *datesArray = [NSMutableArray array];

        for (NSString *date in dates) {
            predicate = [NSPredicate predicateWithFormat:
                         @"section = %@ AND category = %@ AND date = %@",
                         section, category, date];

            NSArray *filteredInput = [input filteredArrayUsingPredicate:predicate];
            if (filteredInput.count > 0) {
                NSMutableArray *filteredOutput = [NSMutableArray arrayWithCapacity:filteredInput.count];

                [filteredInput enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
                    [filteredOutput addObject:
                     [NSDictionary dictionaryWithObjectsAndKeys:
                      [obj objectForKey:@"key1"], @"key1",
                      [obj objectForKey:@"key2"], @"key2", nil]
                     ];
                }];

                if (filteredOutput.count > 0)
                    [datesArray addObject:filteredOutput];
            }
        }
        if (datesArray.count > 0)
            [categoriesDictionary setObject:datesArray forKey:category];
    }
    if (categoriesDictionary.count > 0)
        [output setObject:categoriesDictionary forKey:section];
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM