簡體   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