代码之家  ›  专栏  ›  技术社区  ›  Jonah

从plist中获取字典数组并基于键的值创建节的最佳方法

  •  1
  • Jonah  · 技术社区  · 16 年前

    我有一个plist,它包含一个带有字典集合的数组。数组中的字典用于创建一个相当复杂的表视图,每个单元格中有2个图像和2行文本。我希望在TableView中基于与“maintext”键对应的值的第一个字母创建节。

    这是plist格式。在本例中,应该有两个部分,一个用于以“a”开头的“maintext”字符串的字典,另一个用于以“b”开头的“maintext”字符串的两个字典。

    <dict>
    <key>Rows</key>
    <array>
        <dict>
            <key>MainText</key>
            <string>A sometext</string>
            <key>SecondaryText</key>
            <string>somemoretext</string>
            <key>PrimaryIcon</key>
            <string>firsticon.png</string>
            <key>SecondaryIcon</key>
            <string>secondicon.png</string>
        </dict>
        <dict>
            <key>MainText</key>
            <string>B sometext</string>
            <key>SecondaryText</key>
            <string>somemoretext</string>
            <key>PrimaryIcon</key>
            <string>firsticon.png</string>
            <key>SecondaryIcon</key>
            <string>secondicon.png</string>
        </dict>
                <dict>
            <key>MainText</key>
            <string>B moreTextStartingWith"B"</string>
            <key>SecondaryText</key>
            <string>somemoretext</string>
            <key>PrimaryIcon</key>
            <string>firsticon.png</string>
            <key>SecondaryIcon</key>
            <string>secondicon.png</string>
        </dict>
    </array>
    

    我已经编写了代码,用于从“maintext”键的字符串中提取第一个字母,对它们进行排序并创建节标题。我还拥有在每个部分中设置正确行数的代码。这是我在viewdidload方法中遇到的一些代码。

    //Create an array sorted by the strings in "MainText" of the AppDelegate.data
        NSSortDescriptor *sortDescriptor;
        sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"MainText" ascending:YES] autorelease];
        NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
        NSArray *sortedArray;
        sortedArray = [[AppDelegate.data objectForKey:@"Rows"] sortedArrayUsingDescriptors:sortDescriptors];
    
    
    //Now set tableDataSource equal to sortedArray
        self.tableDataSource = sortedArray;
    
    //Create a set of the first letters used by the strings in MainText
        NSMutableSet *firstCharacters = [NSMutableSet setWithCapacity:0];
        for( NSString *string in [tableDataSource valueForKey:@"MainText"] )
            [firstCharacters addObject:[string substringToIndex:1]];
    
    //Create a sorted array of first letters used by strings in MainText
        self.arrayOfInitialLetters = [[firstCharacters allObjects] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
    
    //Create an array of the MainText of each item in tableDataSource   
        NSMutableArray * mainTextArray = [tableDataSource valueForKey:@"MainText"];
    

    我应该如何在cellForRowatindexPath方法中获得正确的行?当前,每个部分只显示从第一个开始的相同单元格。我需要在我的数据源中定义不同的部分。谢谢你的帮助,这是一场真正的斗争!

    2 回复  |  直到 11 年前
        1
  •  1
  •   Jonah    16 年前

    我终于把它做好了。这是我的viewdidload方法的代码。这可能不是最干净的方法来获得我的结果,但它工作得很好!不过,我欢迎任何建议。

    - (void)viewDidLoad {
    [super viewDidLoad];
    
    // Load the UICustomTabViewController
        UICustomTabViewController *tvController = [[UICustomTabViewController alloc]
             initWithNibName:@"TabViewController" bundle:nil];
        self.tabViewController = tvController;
        [tvController release];
    
        YourAppDelegate *AppDelegate = (YourAppDelegate *)[[UIApplication
             sharedApplication] delegate];
    
    
    // Create an array sorted by CommonName of the AppDelegate.data
        NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"CommonName" ascending:YES] autorelease];
        NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
        NSArray *sortedArray;
        sortedArray = [[AppDelegate.data objectForKey:@"Rows"] sortedArrayUsingDescriptors:sortDescriptors];
    
    // Now set tableDataSource equal to sortedArray
        self.tableDataSource = sortedArray;
    
    // Create a set of the first letters used by the strings in CommonName and sort them
        NSMutableSet *firstCharacters = [NSMutableSet setWithCapacity:0];
        for( NSString *string in [tableDataSource valueForKey:@"CommonName"] )
            [firstCharacters addObject:[string substringToIndex:1]];
            self.arrayOfInitialLetters = [[firstCharacters allObjects]
            sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
    
        self.sectionedDictionaryByFirstLetter = [NSMutableDictionary dictionary];           
    
    // All data sorted in sections by initial letter of "CommonName"
        NSDictionary *eachItemList;  //PUTS ALL THE DATA FOR EACH ITEM IN IT'S OWN SECTION
        for (eachItemList in tableDataSource)   //eachElementList is an array with a section for each item
        {
            NSDictionary *aDictionary = [[NSDictionary alloc] initWithDictionary:eachItemList];
            NSString *firstLetterString;
            firstLetterString = [[aDictionary valueForKey:@"CommonName"]substringToIndex:1];
    
            NSMutableArray *existingArray;
    
            if (existingArray = [sectionedDictionaryByFirstLetter valueForKey:firstLetterString]) 
            {
                [existingArray addObject:eachItemList];
            } else {
                NSMutableArray *tempArray = [NSMutableArray array];
                [sectionedDictionaryByFirstLetter setObject:tempArray forKey:firstLetterString];
                [tempArray addObject:eachItemList];
            }
            [aDictionary release];
            [eachItemList release];
            NSLog(@"nameIndexesDictionary:%@", sectionedDictionaryByFirstLetter);
        }
    

    这就是我在cellForRowatindexPath方法中获得正确行的方法

        NSInteger section = [indexPath section];
        NSString *key = [arrayOfInitialLetters objectAtIndex:section];  
        NSArray *nameSection = [sectionedDictionaryByFirstLetter objectForKey:key];
        NSDictionary *dictionary = [nameSection objectAtIndex:indexPath.row];
    
        2
  •  0
  •   Matt Long    16 年前

    您的XML看起来错误。看起来应该是这样的:

    <dict>
    <key>Rows</key>
    <array>
            <dict>
                    <key>MainText</key>
                    <string>A sometext</string>
                    <key>SecondaryText</key>
                    <string>somemoretext</string>
                    <key>PrimaryIcon</key>
                    <string>firsticon.png</string>
                    <key>SecondaryIcon</key>
                    <string>secondicon.png</string>
            </dict>
            <dict>
                    <key>MainText</key>
                    <string>B sometext</string>
                    <key>SecondaryText</key>
                    <string>somemoretext</string>
                    <key>PrimaryIcon</key>
                    <string>firsticon.png</string>
                    <key>SecondaryIcon</key>
                    <string>secondicon.png</string>
            </dict>
    </array>
    </dict>
    

    您可以为nsdictionary创建一个类别,该类别允许您对数据进行排序。像这样:

    @interface NSDictionary (Sorting) 
    
    -(NSComparisonResult)compareRows:(NSDictionary*)row;
    
    @end
    
    @implementation NSDictionary (Sorting)
    
    -(NSComparisonResult)compareRows:(NSDictionary*)row;
    {
        NSString *rowMainText = [row objectForKey:@"MainText"];
        NSString *selfMainText = [self objectForKey:@"MainText"];
    
        return [selfMaintext localizedCompare:rowMainText];
    }
    @end
    

    然后您可以这样执行排序:

    [rows sortUsingSelector:@selector(compareRow:)];
    

    变量 需要是可变的,因为排序将在内部执行。