5

NSMutableArrayオブジェクトとしてエンティティクラスオブジェクトを持つがあります。ここで、個別のオブジェクトを削除します。次の例を検討してください

Entity *entity = [[Entity alloc] init]; 
entity.iUserId = 1;
entity.iUserName = @"Giri"
[arr addObject:entity];

Entity *entity = [[Entity alloc] init]; 
entity.iUserId = 2;
entity.iUserName = @"Sunil"
[arr addObject:entity];

Entity *entity = [[Entity alloc] init]; 
entity.iUserId = 3;
entity.iUserName = @"Giri"
[arr addObject:entity];

Arrayここで、重複するiUserNameを削除して、に2つのオブジェクトのみが必要です。predicate私は反復による方法を知っていますが、他の方法のように反復せずにそれを望んでいます。誰かが知っているなら、私を助けてください。使ってみ[arr valueForKeyPath:@"distinctUnionOfObjects.iUsername"];ましたが、オブジェクト全体が返されません。

この質問は、以前に尋ねられた質問とはまったく異なります。以前に尋ねられた質問は、個別のオブジェクトを取得することは正しいかどうかですが、ループを使用しているため、これは望ましくありません。私はそれNSPredicateまたはループを回避する他の単純なオプションが欲しいです。

4

2 に答える 2

4

編集:配列を手動でループして新しい配列を構築せずに、やりたいことを行うことはできません。以下の答えは、重複が最大2つしかないことを前提としているため、機能しません。

NSMutableArray *filteredArray = [NSMutableArray array];

for (Entity *entity in arr)
{
    BOOL hasDuplicate = [[filteredArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"iUserName == %@", entity.iUserName]] count] > 0;

    if (!hasDuplicate)
    {
        [filteredArray addObject:entity];
    }
}

これにより、フィルター処理された配列が構築されるときに重複が検索されます。

元の回答を開始

インスタンスがで戻る必要があるNSSetため、を使用することはできません。これは、名前を一意の識別子として使用するべきではないため、お勧めできません。EntityNSOrderedSamecompareTo:

述語を使用することはできますが、O(n^2)最適化を行わなくても、ある時間内に配列をループします。

NSArray *filteredArray = [arr filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(Entity *evaluatedObject, NSDictionary *bindings) {
    return [[arr filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"iUserName == %@", evaluatedObject.iUserName]] count] > 1;
}]];

それはうまくいくでしょう。iUserName最初にプロパティで配列を並べ替え、並べ替えられた配列に対して線形スキャンを実行することで、さらに高速化できます(最初の重複が表示されたら停止します)。小さいサンプルサイズ(たとえば、1万未満)を扱っている場合、これは多くの作業です。おそらく時間の価値がないので、上記のコードを使用してください。

于 2013-02-13T14:31:32.160 に答える