6

これは iOS 用ではなく、OSX 用であることに注意してください。

私は他のSOの質問でいくつかの解決策を見て試しましたが、どれもうまくいかないようです。

配列から一意の年のセットを取得したい。

私のコードはこれです:

NSMutableArray * unique = [NSMutableArray array];
        NSMutableSet * processed = [NSMutableSet set];
        for (yearString in yearStringArray) {
            if (![processed containsObject:yearString] == NO) {
                [unique addObject:yearString];
            }
            [processed addObject:yearString];
        }

        NSLog(@"unique: %@",unique );
        NSLog(@"processed: %@",processed );

    }];

The console returns:

unique: (
        (
        1941,
        1942,
        1943,
        1945,
        1948,
        1948,
        1948,
        1949
    )

processed: {(
        (
        1941,
        1942,
        1943,
        1945,
        1948,
        1948,
        1948,
        1949
    )
)}

1948 が 1 つだけ欲しいのですが、助けていただければ幸いです。

更新:すべての回答に感謝します。来てください!

これらは私が今試したコードスニップです:

1.

for (yearString in yearStringArray) {
            if ([processed containsObject:yearString] == NO) {
                [unique addObject:yearString];
            }
            [processed addObject:yearString];
        }

2.

   NSString *yearString = [[NSString alloc] init];
    NSArray *objectArray = [[NSArray alloc] init];
    [objectArray = objects copy];

    for (int j = 0; j <= objectArray.count; j++) {
        NSString *yearString = [objectArray valueForKey:@"year"];
        [yearStringArray addObject:yearString];
    }


    NSMutableArray * unique = [NSMutableArray array];
    NSMutableSet * processed = [NSMutableSet set];


    for (yearString in yearStringArray) {

        [unique addObject:yearString];
        [processed addObject:yearString];
    }

    NSArray *processed2 = [[NSSet setWithArray:unique] allObjects];
    NSLog(@"unique: %@",unique );
    NSLog(@"processed: %@",processed );
    NSLog(@"processed2: %@",processed2 );
    //[self setYears];
}];

3.

NSString *yearString = [[NSString alloc] init];
    NSArray *objectArray = [[NSArray alloc] init];
    [objectArray = objects copy];

    for (int j = 0; j <= objectArray.count; j++) {
        yearString = [objectArray valueForKey:@"year"];
        [yearStringArray addObject:yearString];
    }



    NSArray *uniqueYears = [yearStringArray valueForKeyPath:@"@distinctUnionOfObjects.self"];
    NSLog(@"uniqueYears: %@", uniqueYears);


}];



}

まだ一意の年を取得していません..

4

4 に答える 4

27

簡単な方法はNSSet、重複した配列から を作成することです。結果は、定義上、一意のオブジェクトのみを格納するセットになります。次に、NSSet の-allObjectsメソッドを使用して を に変換しNSSetますNSArray。唯一の欠点は、に変換することで元の順序が失われることNSSetです。

NSArray *uniqueArray = [[NSSet setWithArray:duplicateArray] allObjects];

順序を維持する必要があり、10.7 以降が必要な場合は、NSOrderedSet.

NSArray *uniqueArray = [[NSOrderedSet orderedSetWithArray:duplicateArray] array];

編集:

WWDC 2013セッション 228 - Cocoa と Cocoa Touch の隠された宝石のMattt Thompsonのおかげで、中間セットを作成しない別の方法があります。

NSArray *uniqueArray = [duplicateArray valueForKeyPath:@"@distinctUnionOfObjects.self"]
于 2013-10-15T05:38:36.583 に答える
8

配列を使用して、valueForKeyPathに設定できますdistinctUnionOfObjects.self

NSArray *yearsArray = @[@"1943", @"1945", @"1948", @"1948", @"1948", @"1949"];
NSArray *uniqueYears = [yearsArray valueForKeyPath:@"@distinctUnionOfObjects.self"];
NSLog(@"uniqueYears: %@", uniqueYears);
于 2013-10-15T05:39:54.493 に答える
2

あなたが提供したものNSLog:

unique: (
    (
    1941,
    1942,
    1943,
    1945,
    1948,
    1948,
    1948,
    1949
    ) 
) 

これは文字列の配列ではありません。これは、それ自体が配列である 1 つのオブジェクトを持つ配列です。yearStringArrayそれはそれが同じ構造を持っていることを示唆しています。明らかに、あなたのコード (およびその変数の名前) は、そうではないはずだと考えたことを示唆しています。

yearStringArray実際に文字列の配列を作成するために作成されたものを修正するか、この構造を反映するようにコードを変更する必要がありますyearStringArray

for (yearString in yearStringArray[0]) 
{
    ....
}
于 2013-10-15T06:48:10.047 に答える
1

ここにバグがあります。

if (![processed containsObject:yearString] == NO)

使用する必要があります

if ([processed containsObject:yearString] == NO)

また

if (![processed containsObject:yearString])
于 2013-10-15T05:38:30.000 に答える