FreeAppl3
FreeAppl3

Reputation: 858

Group Array of Dictionaries containing Dictionaries with Duplicate Values

I currently am working on a grouped tableView. I have it working but want to change my incoming arrays into dictionaries to provide more useful information in tableview. The DictionaryHolder has all different keys which is the name, it contains a dictionary with "mainTheme" key some of these mainKeys match and I would like to compile those matching dictionary into array and then back into a new dictionary with new key "subThemes" which is the array of dictionary set contains matches of "mainTheme"... Ive hit a wall and don't know how to approach this which methods would be the fastest because at times there could be a lot of dictionaries being created and sorted. Any help would be greatly appreciated!

-(NSMutableArray*)themesDictFromThemesPlists:(NSMutableArray*)allThemesonDevice{

NSMutableDictionary *compiledThemesDictionaryHolder = [[NSMutableDictionary alloc]init];
NSMutableArray *returnedDict = [[NSMutableArray alloc]init];
NSMutableDictionary *mainThemeCompiled = [[NSMutableDictionary alloc]init];
NSMutableDictionary *themePlistDict = nil;
NSString *packageName= nil;
NSString*fullPlistStr = nil;
NSString *themeStringToDeconstruct = nil;


//create dictionary for each theme
NSMutableArray *allPckgNames = [[NSMutableArray alloc]init];
for (NSString *actualName in allThemesonDevice) {

    themeStringToDeconstruct = actualName;
    if ([themeStringToDeconstruct hasSuffix:@".theme"]) {
        themeStringToDeconstruct = [themeStringToDeconstruct stringByReplacingOccurrencesOfString:@".theme" withString:@""];
    }
    themeStringToDeconstruct = [themeStringToDeconstruct stringByReplacingOccurrencesOfString:@"_" withString:@" "];
    NSArray *theWords = [themeStringToDeconstruct componentsSeparatedByString:@" "];
    NSString *nameWithoutTags = [theWords objectAtIndex:0];
    //NSLog (@"ICONOMATIC OBJECT AT INDEX 0 %@",newName);


    fullPlistStr = [NSString stringWithFormat:@"/Library/Themes/%@/Info.plist",actualName];
    themePlistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:fullPlistStr];
    packageName = [themePlistDict objectForKey:@"PackageName"];
    //NSLog (@"ThemePlistDict: %@",themePlistDict);
    //NSLog (@"ICONOMATIC Actual Name : %@ PackageName: %@",actualName,packageName);


    if (packageName) {

        NSMutableDictionary *compiledTheme = [[NSMutableDictionary alloc]init];
        [compiledTheme setValue:actualName forKey:@"fullThemeName"];
        [compiledTheme setValue:nameWithoutTags forKey:@"themeName"];
        [compiledTheme setValue:packageName forKey:@"mainTheme"];

        //can add more icons
        if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"/Library/Themes/%@/icon.png",actualName]]) {
            [compiledTheme setValue:[NSString stringWithFormat:@"/Library/Themes/%@/icon.png",actualName]  forKey:@"icon1"];

        }

        NSLog (@"Iconomatic ADD compiledTheme %@ ",compiledTheme);

        [compiledThemesDictionaryHolder setValue:compiledTheme forKey:actualName];
        //[compiledThemesDictionaryHolder addObject:compiledTheme];


        [allPckgNames addObject:packageName];

}

 }



NSLog (@"Iconomatic compiledThemesDictionaryHolder %@ ",compiledThemesDictionaryHolder);

NSLog (@"Iconomatic ALLPckgs: %@",allPckgNames);



/*create Main Dictionary for each package
 This is where Ive hit a wall. I need to determine which dictionaries have matching     
"mainTheme" keysValues and compile into array of dictionaries to store in new dictionary   
(mainThemeCompiled) which will be added into returnDict which is a array that populates the 
tableview by keys*/

 //NSSet or descriptorByKeys I don't know how to approach this
//NSMutableArray *tempStorage = [[NSMutableArray alloc]init];

for (NSDictionary *themeDict in compiledThemesDictionaryHolder) {

    NSLog (@"Iconomatic themeDict: %@",themeDict);

    [mainThemeCompiled setValue:themeDict forKey:@"package"];
   }


NSLog(@"Iconomatic compiledThemesDictionaryHolder %@",returnedDict);


return returnedDict;
 }




    Iconomatic compiledThemesDictionaryHolder {
   "Bohemic NOIR alt.theme" =     {
    fullThemeName = "Bohemic NOIR alt.theme";
    icon1 = "/Library/Themes/Bohemic NOIR alt.theme/icon.png";
    mainTheme = BohemicNOIR;
    themeName = Bohemic;
   };
    "Bohemic NOIR badges.theme" =     {
    fullThemeName = "Bohemic NOIR badges.theme";
    icon1 = "/Library/Themes/Bohemic NOIR badges.theme/icon.png";
    mainTheme = BohemicNOIR;
    themeName = Bohemic;
   };
   "Bohemic NOIR iPad calendar.theme" =     {
    fullThemeName = "Bohemic NOIR iPad calendar.theme";
    icon1 = "/Library/Themes/Bohemic NOIR iPad calendar.theme/icon.png";
    mainTheme = BohemicNOIR;
    themeName = Bohemic;
   };
   "Bohemic NOIR mask" =     {
    fullThemeName = "Bohemic NOIR mask";
    icon1 = "/Library/Themes/Bohemic NOIR mask/icon.png";
    mainTheme = BohemicNOIR;
    themeName = Bohemic;
  };

Upvotes: 0

Views: 106

Answers (1)

FreeAppl3
FreeAppl3

Reputation: 858

Ok so here was my overall solution. The main issue was determining the available matching objects in array of dictionary and was solved by using indexesOfObjectsPassingTest and enumerateIndexesUsingBlock

 -(NSMutableArray*)themesDictFromThemesPlists:(NSMutableArray*)allThemesonDevice{

NSMutableArray *compiledThemesDictionaryHolder = [[NSMutableArray alloc]init];
NSMutableArray *returnedArrayOfDicts = [[NSMutableArray alloc]init];
NSMutableDictionary *themePlistDict = nil;
NSString *packageName= nil;
NSString*fullPlistStr = nil;


//create dictionary for each theme
NSMutableArray *allPckgNames = [[NSMutableArray alloc]init];
for (NSString *actualName in allThemesonDevice) {

    fullPlistStr = [NSString stringWithFormat:@"/Library/Themes/%@/Info.plist",actualName];
    themePlistDict = [[NSMutableDictionary alloc] initWithContentsOfFile:fullPlistStr];
    packageName = [themePlistDict objectForKey:@"PackageName"];
    //NSLog (@"ThemePlistDict: %@",themePlistDict);
    //NSLog (@"ICONOMATIC Actual Name : %@ PackageName: %@",actualName,packageName);


    if (packageName) {

        NSMutableDictionary *compiledTheme = [[NSMutableDictionary alloc]init];
        [compiledTheme setValue:actualName forKey:@"fullThemeName"];
        [compiledTheme setValue:packageName forKey:@"mainTheme"];

        if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"/Library/Themes/%@/Icon.png",actualName]]) {
            [compiledTheme setValue:[NSString stringWithFormat:@"/Library/Themes/%@/Icon.png",actualName]  forKey:@"icon1"];
            [compiledTheme setValue:@"prominate" forKey:@"prominate"];
            //can add more icons to dict
        }
        if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"/Library/Themes/%@/icon.png",actualName]]) {
            [compiledTheme setValue:[NSString stringWithFormat:@"/Library/Themes/%@/icon.png",actualName]  forKey:@"icon1"];
            //can add more icons to dict

        }
        //NSLog (@"Iconomatic ADD compiledTheme %@ ",compiledTheme);

        //these arrays below should have same indexes to objects but (allPackgNames) can easliy be grouped
        [compiledThemesDictionaryHolder addObject:compiledTheme];

        [allPckgNames addObject:packageName];

}
    }


 //NSLog (@"Iconomatic compiledThemesDictionaryHolder %@ ",compiledThemesDictionaryHolder);
// NSLog (@"Iconomatic ALLPckgs: %@",allPckgNames);



//create Main Dictionary for each package
NSMutableArray *tempNameArrayToSort = [[NSMutableArray alloc]initWithArray:allPckgNames];
int mainThemesIndex = 0;
for (NSString *mainThemeName in tempNameArrayToSort) {

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

    //check for pckg name. Array may contain several matches so remove those at end of loop
    if ([allPckgNames containsObject:mainThemeName]) {

        //gather index set of any matches
        NSIndexSet *indxs = [compiledThemesDictionaryHolder indexesOfObjectsPassingTest:^BOOL(NSDictionary *dict, NSUInteger idx, BOOL *stop) {
            return ([dict[@"mainTheme"]isEqualToString:mainThemeName]);
        }];
        //NSLog(@"Iconomatic indexSet %@",indxs);

        //enumerate those index sets to grab dictionaries and store in (subThemes)
        NSMutableArray *subThemeArray = [[NSMutableArray alloc]init];
        [indxs enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
            // NSLog(@"Iconomatic dict %@ at index %lu",[compiledThemesDictionaryHolder objectAtIndex:idx],idx);
            [subThemeArray addObject:[compiledThemesDictionaryHolder objectAtIndex:idx]];
        }];


        //start creating mainDictionary for MainTheme

        NSDictionary *themeDict = [compiledThemesDictionaryHolder objectAtIndex:mainThemesIndex];
        NSString *fullThemeName = [themeDict objectForKey:@"fullThemeName"];

        NSLog (@"ICONOMATIC BUILD~ MainTheme: %@ Dict: %@ subThemes: %@",mainThemeName,themeDict,subThemeArray);

        [mainThemeDict setValue:fullThemeName forKey:@"fullThemeName"];
        [mainThemeDict setValue:[themeDict objectForKey:@"mainTheme"] forKey:@"themeName"];

        UIImage *icon1 = nil;
        UIImage *icon2 = nil;
        UIImage *icon3 = nil;
        UIImage *icon4 = nil;

        if ([subThemeArray count] >=1) {

            [mainThemeDict setValue:subThemeArray forKey:@"themesSubThemes"];
            [mainThemeDict setValue:[NSNumber numberWithInt:[subThemeArray count]] forKey:@"themeSubCount"];

            for (NSDictionary *subDict in subThemeArray) {


                NSString *mainthemeIcons = [NSString stringWithFormat:@"/Library/Themes/%@/IconBundles",[subDict objectForKey:@"fullThemeName"]];

                if ([subDict objectForKey:@"prominate"]) {

                    icon1 = [UIImage imageWithContentsOfFile:[subDict objectForKey:@"icon1"]];

                    if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/com.apple.AppStore-large.png",mainthemeIcons]]) {

                        icon1 = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"/Library/Themes/%@/IconBundles/com.apple.AppStore-large.png",[subDict objectForKey:@"fullThemeName"]]];
                        icon2 = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"/Library/Themes/%@/IconBundles/com.apple.Music-large.png",[subDict objectForKey:@"fullThemeName"]]];
                        icon3 = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"/Library/Themes/%@/IconBundles/com.apple.MobileSMS-large.png",[subDict objectForKey:@"fullThemeName"]]];
                        icon4 = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"/Library/Themes/%@/IconBundles/com.apple.mobilesafari-large.png",[subDict objectForKey:@"fullThemeName"]]];

                    }

                }else{

                    if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/com.apple.AppStore-large.png",mainthemeIcons]]) {

                        icon1 = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"/Library/Themes/%@/IconBundles/com.apple.AppStore-large.png",[subDict objectForKey:@"fullThemeName"]]];
                        icon2 = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"/Library/Themes/%@/IconBundles/com.apple.Music-large.png",[subDict objectForKey:@"fullThemeName"]]];
                        icon3 = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"/Library/Themes/%@/IconBundles/com.apple.MobileSMS-large.png",[subDict objectForKey:@"fullThemeName"]]];
                        icon4 = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"/Library/Themes/%@/IconBundles/com.apple.mobilesafari-large.png",[subDict objectForKey:@"fullThemeName"]]];
                    }
                }
            }
        }
        //nosubthemes
        else{
            if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/com.apple.AppStore-large.png",fullThemeName]]) {

                icon1 = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"/Library/Themes/%@/IconBundles/com.apple.AppStore-large.png",fullThemeName]];
                icon2 = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"/Library/Themes/%@/IconBundles/com.apple.Music-large.png",fullThemeName]];
                icon3 = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"/Library/Themes/%@/IconBundles/com.apple.MobileSMS-large.png",fullThemeName]];
                icon4 = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"/Library/Themes/%@/IconBundles/com.apple.mobilesafari-large.png",fullThemeName]];
            }

        }



        if (icon1) {
            [mainThemeDict setValue:icon1  forKey:@"icon1"];
        }
        if (icon2) {
            [mainThemeDict setValue:icon2  forKey:@"icon2"];
        }
        if (icon3) {
            [mainThemeDict setValue:icon3  forKey:@"icon3"];
        }
        if (icon4) {
            [mainThemeDict setValue:icon4  forKey:@"icon4"];
        }



        if ([activeIconomaticThemes containsObject:fullThemeName]) {
            [mainThemeDict setValue:[NSNumber numberWithBool:YES] forKey:@"isActive"];
        }
        else{
            [mainThemeDict setValue:[NSNumber numberWithBool:NO] forKey:@"isActive"];
        }


        [allPckgNames removeObject:mainThemeName];
        //end of creating mainThemeDict
    }

    mainThemesIndex = mainThemesIndex+1;

    if ([mainThemeDict count]) {
        [returnedArrayOfDicts addObject:mainThemeDict];
    }
    //end of (mainTheme in allPackNames)
}


NSLog(@"Iconomatic returnedArrayOfDicts %@",returnedArrayOfDicts);

return returnedArrayOfDicts;
}

OutPut of Main Theme is now

 ICONOMATIC BUILD~ MainTheme: Lotus Dark Dict: {
fullThemeName = "Lotus Dark Apps";
mainTheme = "Lotus Dark";
 } subThemes: (
    {
    fullThemeName = "Lotus Dark Apps";
    mainTheme = "Lotus Dark";
},
    {
    fullThemeName = "Lotus Dark Apps (Alternate)";
    mainTheme = "Lotus Dark";
},
    {
    fullThemeName = "Lotus Dark Calendar";
    mainTheme = "Lotus Dark";
},
    {
    fullThemeName = "Lotus Dark Icon Effect";
    mainTheme = "Lotus Dark";
},
    {
    fullThemeName = "Lotus Dark Mask";
    mainTheme = "Lotus Dark";
},
    {
    fullThemeName = "Lotus Dark Settings";
    mainTheme = "Lotus Dark";
},
    {
    fullThemeName = "Lotus Dark Widgets";
    mainTheme = "Lotus Dark";
}
 )

and Final is:

  Iconomatic returnedArrayOfDicts (
    {
    fullThemeName = "Bohemic NOIR alt.theme";
    icon1 = "<UIImage:0x281f48b40 anonymous {300, 300}>";
    icon2 = "<UIImage:0x281f5f9f0 anonymous {300, 300}>";
    icon3 = "<UIImage:0x281f5fba0 anonymous {300, 300}>";
    icon4 = "<UIImage:0x281f5fcc0 anonymous {300, 300}>";
    isActive = 1;
    themeName = BohemicNOIR;
    themeSubCount = 7;
    themesSubThemes =         (
                    {
            fullThemeName = "Bohemic NOIR alt.theme";
            icon1 = "/Library/Themes/Bohemic NOIR alt.theme/icon.png";
            mainTheme = BohemicNOIR;
        },
                    {
            fullThemeName = "Bohemic NOIR badges.theme";
            icon1 = "/Library/Themes/Bohemic NOIR badges.theme/icon.png";
            mainTheme = BohemicNOIR;
        },

Upvotes: 0

Related Questions