1

この問題を調べようとしましたが、運が悪かったので、オブジェクトが不変配列でもあるキーとオブジェクトの「不変ディクショナリ」を作成する関数を構築したいと考えています。

この関数に渡すのは、作成したオブジェクトの配列です。各オブジェクトには、ディクショナリ内のオブジェクトをグループ化するために使用するキー プロパティがあります。

私はこれを思いつき、テストして動作しましたが、これを行うためのより良い/安全な方法があるかどうかを確認したいと思います.

私は ARC を使用しており、関数から戻ったときにすべてが不変であることを確認したいと考えています。

- (NSDictionary* )testFunction:(NSArray *)arrayOfObjects
{
    NSMutableDictionary *tmpMutableDic = [[NSMutableDictionary alloc] init];

    for(MyCustomObject *obj in arrayOfObjects)
    {
        if ([tmpMutableDic objectForKey:obj.key] == nil)
        {
            // First time we get this key. add key/value paid where the value is immutable array
            [tmpMutableDic setObject:[NSArray arrayWithObject:obj] forKey:obj.key];
        }
        else
        {
            // We got this key before so, build a Mutable array from the existing immutable array and add the object then, convert it to immutable and store it back in the dictionary.
            NSMutableArray *tmpMutableArray = [NSMutableArray arrayWithArray:[tmpMutableDic objectForKey:obj.key]];
            [tmpMutableArray addObject:obj];
            [tmpMutableDic setObject:[tmpMutableArray copy] forKey:obj.key];
        }
    }

   // Return an immutable version of the dictionary.
   return [tmpMutableDic copy];
}
4

2 に答える 2

2

コピペが多いと思います。要素を追加するたびにコピーするのではなく、最後まで可変配列を不変配列に変換するのを待ちます。

- (NSDictionary *)testFunction:(NSArray *)arrayOfObjects
{
    NSMutableDictionary *tmpMutableDic = [[NSMutableDictionary alloc] init];

    for(MyCustomObject *obj in arrayOfObjects)
    {
        if ([tmpMutableDic objectForKey:obj.key] == nil)
        {
            // First time we got this key, add array
            [tmpMutableDic setObject:[[NSMutableArray alloc] init] forKey:obj.key];
        }
        // Add the object
        [[tmpMutableDic objectForKey:obj.key] addObject:obj];
    }

    // Convert mutable arrays to immutable
    for (NSString *key in tmpMutableDic.allkeys) {
        [tmpMutableDic setObject:[[tmpMutableDic objectForKey:key] copy] forKey:key];
    }

    // Return an immutable version of the dictionary.
    return [tmpMutableDic copy];
}
于 2013-08-22T20:54:53.133 に答える
0

1 対多の辞書の組み込みの概念がないため、記述した内容を正確に実現するためのより適切な方法はないと思います。他の一般的な操作の全体にあるような 1 行の構文は確かにありません。

とはいえ、マイナーな提案は次のとおりです。

キー値コーディングを使用して、キー付きプロパティを読み取ります。したがって、への参照を へobj.keyの単一の呼び出しに置き換え[obj valueForKeyPath:keyPath]keyPath、パラメーターとして使用します。次に、このコードを 1 回だけ記述する必要があります。

obj.key安全のために、そうではないことを確認する必要がありnilます。[tmpMutableDic setObject:... forKey:nil]辞書はキーに対して値を格納できないため、例外が発生しますnil

copy不変の辞書を返しますが、コピーが浅いため、その中の値は変更可能な配列のままです。不変の配列を明示的に返したい場合は、少し深いコピー関数をすばやく作成する必要があります。

その時点で、キーに基づいて着信配列をソートし、キーの値が変化するたびに新しい配列を作成するアルゴリズムに切り替えることを好む場合があります。その利点は、配列を使い終わった瞬間を常に知っているので、その配列をcopy辞書に保存し、後で少し深いコピーを切り取ることができますが、ソートのコストはかかります.

于 2013-08-22T20:06:28.103 に答える