0

使用している nsarray を nsdictionary に変換したい

- (NSDictionary *) indexKeyedDictionaryFromArray:(NSArray *)array
{
    id objectInstance;
    NSUInteger indexKey = 0;

    NSMutableDictionary *mutableDictionary = [[NSMutableDictionary alloc] init];
    for (objectInstance in array)
        [mutableDictionary setObject:objectInstance forKey:[NSNumber numberWithUnsignedInt:indexKey++]];

    return (NSDictionary *)[mutableDictionary autorelease];
}

出力結果は次のとおりです。

{
    0 =     {
        Event = "";
        ID = 1;    };
    3 =     {
        Event = "";
        ID = 77;    };
    2 =     {
        Event = "";
        ID = 23;    };
    1 =     {
        Event = "";
        ID = 45;    };
    7 =     {
        Event = "";
        ID = 10;    };
    5 =     {
        Event = "";
        ID = 26;    };
    6 =     {
Event = "";
        ID = 27;
    };
    8 =     {
Event = "";
        ID = 28;
    };
}

nsdictionary に変換した後、nsdictionary の順序が元の順序と一致しません。nsarray に同じ順序で表示したいのですが、方法がわかりません。手伝って頂けますか?

4

3 に答える 3

1

コメント内の @ACB と @Zaph への返信から正しく理解できれば、次のことを行う必要があります。

キーによって順序付けられたオブジェクト値に整数キーをマッピングするコレクションを維持します。

私が正しく理解していれば、配列の整数キーには「穴」がないため、配列は目的には十分ではありません。ただし、穴を考慮する必要があります。質問の出力では、4 のキーと値のペアが欠落しています。このため、辞書はあなたにとって魅力的です。

残念ながら、 @Zaph が指摘しているように、ディクショナリでは、含まれるキーと値のペアの順序を維持することはできません。ただし、 a のキーで並べ替えられたディクショナリの値を表示したいだけだと言いますUITableView。おそらく、ディクショナリwriteToFile:atomically:の内容がテーブル ビューで正しい順序で表示される限り、ディクショナリが ( を使用して) ディスクにシリアル化される順序は重要ではありません。

この目的のために、次のように辞書を使用できます。まず、 class が必要PFXKeyValuePairです。

@interface PFXKeyValuePair : NSObject
@property (nonatomic) id<NSCopying> key;
@property (nonatomic) id value;
+ (PFXKeyValuePair *)pairWithValue:(id)value forKey:(id<NSCopying>)key;
+ (NSArray *)pairsWithValues:(NSArray *)values forKeys:(NSArray *)keys;
@end

@implementation PFXKeyValuePair
+ (PFXKeyValuePair *)pairWithValue:(id)value forKey:(id<NSCopying>)key
{
    PFXKeyValuePair *pair = [[PFXKeyValuePair alloc] init];
    pair.value = value;
    pair.key = key;
    return pair;
}
+ (NSArray *)pairsWithValues:(NSArray *)values forKeys:(NSArray *)keys
{
    NSAssert(values.count == keys.count, @"The array of values must be the same size as the array of keys.");
    NSUInteger count = values.count;
    NSMutableArray *mutableRes = [NSMutableArray array];
    for (NSUInteger index = 0; index < count; index++) {
        PFXKeyValuePair *pair = [PFXKeyValuePair pairWithValue:values[index] forKey:keys[index]];
        [mutableRes addObject:pair];
    }
    return [mutableRes copy];
}
@end

次に、 のカテゴリ メソッドが必要ですNSDictionary

@interface NSDictionary (PFXAdditions)
- (NSArray *)pfx_keyValuePairsSortedByKeyUsingComparator:(NSComparator)comparator;
@end

@implementation NSDictionary (PFXAdditions)
- (NSArray *)pfx_keyValuePairsSortedByKeyUsingComparator:(NSComparator)comparator
{
    NSArray *sortedKeys = [self.allKeys sortedArrayUsingComparator:comparator];
    NSArray *sortedValues = [self objectsForKeys:sortedKeys notFoundMarker:[NSNull null]];
    return [PFXKeyValuePair pairsWithValues:sortedValues forKeys:sortedKeys];
}
@end

: 上記のPFXpfxはプレースホルダーです。プロジェクトに適したプレフィックスに置き換える必要があります。

次に、このカテゴリ メソッドを使用して、UITableView. プロパティがあるとしましょう

@property (nonatomic) NSDictionary *events;

テーブル ビューには、これらのイベントが表示されるセクションが 1 つだけあるとします。

–tableView:numberOfRowsInSection:次に、次のようにUITableViewControllerサブクラスに実装できます。

– (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.events.count;
}

そして、実装内で、–tableView:numberOfRowsInSection:次のように使用する辞書内の適切なエントリを決定できます。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //...
    NSArray *pairs = [self.events pfx_keyValuePairsSortedByKeyUsingComparator:^(id obj1, id obj2) {
        NSNumber *key1 = (NSNumber *)obj1;
        NSNumber *key2 = (NSNumber *)obj2;
        return [key1 compare:key2];
    }];

    NSUInteger index = [indexPath indexAtPosition:1];
    PFXKeyValuePair *pair = pairs[index];
    /*
    At this point, pair.value will be a dictionary as in your output above 
    holding a value for the key @"Event" and a value for the key @"ID".
    */
    //...
}

これは、プロパティを作成し、必要な場合にのみ計算することで高速化できますpairs(たとえば、pairsテーブルのデータをリロードする直前にのみ計算するなど)。

:このアプローチを使用すると、辞書は(を呼び出すときに-writeToDisk:atomically:)「順番に」ディスクにシリアル化されず、出力は質問と同じように見えます。ただし、これは問題ではありません。データがテーブル ビューでユーザーに表示されるとき、データは希望どおりに並べられます。

于 2013-01-06T20:02:34.130 に答える
1

NSDictionary注文はありません。キーをソートし、それらを使用してエントリにアクセスします。

于 2013-01-06T04:46:09.923 に答える
0

これは、従業員リスト NSMutableArray を取得し、NSMutableDictionary を作成する例の 1 つです。

NSMutableArray *emloyees = [[NSMutableArray alloc]initWithObjects:@"saman",@"Ruchira",@"Rukshan",@"ishan",@"Harsha",@"Ghihan",@"Lakmali",@"Dasuni", nil];

NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (NSString *word in emloyees) {

NSString *firstLetter = [[word substringToIndex:1] uppercaseString];
letterList  = [dict objectForKey:firstLetter];

if (!letterList) {
    letterList = [NSMutableArray array];
    [dict setObject:letterList forKey:firstLetter];
}

[letterList addObject:word];}NSLog(@"dic %@",dict);
于 2015-10-29T07:07:29.730 に答える