如何从数组中获取唯一值

时间:2013-10-15 05:32:34

标签: objective-c macos nsarray nsset

请注意 这适用于OSX,不适用于iOS。

我在其他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

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 个答案:

答案 0 :(得分:25)

一种简单的方法是从数组中创建一个带有重复项的NSSet。结果是一个集合,根据定义只存储唯一对象。然后使用NSSet的-allObjects方法将NSSet转换回NSArray。唯一的缺点是您通过转换为NSSet来丢失原始订单。

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

如果您需要保留订购并且可以要求10.7+,则可以使用NSOrderedSet

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

修改

感谢WWDC 2013 Session 228中的Mattt Thompson - Cocoa和Cocoa Touch中的隐藏宝石, 没有创建中间集的另一种方法。

NSArray *uniqueArray = [duplicateArray valueForKeyPath:@"@distinctUnionOfObjects.self"]

答案 1 :(得分:8)

您可以使用数组的valueForKeyPath并将其设置为distinctUnionOfObjects.self

NSArray *yearsArray = @[@"1943", @"1945", @"1948", @"1948", @"1948", @"1949"];
NSArray *uniqueYears = [yearsArray valueForKeyPath:@"@distinctUnionOfObjects.self"];
NSLog(@"uniqueYears: %@", uniqueYears);

答案 2 :(得分:2)

您提供了NSLog

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

这不是一个字符串数组。这是一个包含一个对象的数组,它本身就是一个数组。这表明yearStringArray具有相同的结构。很明显,你的代码(以及该变量的名称)表明你认为它应该是其他的。

您应该修复创建yearStringArray的任何内容以实际创建字符串数组,或更改代码以反映yearStringArray的此结构,例如,

for (yearString in yearStringArray[0]) 
{
    ....
}

答案 3 :(得分:1)

这是错误。

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

你必须使用

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

if (![processed containsObject:yearString])