如何将NSArray的字符串转换为一个唯一字符串数组,顺序相同?

时间:2010-11-17 22:28:58

标签: iphone objective-c ios nsarray nsset

如果您有NSArray字符串

{ @"ONE", @"ONE", @"ONE", "TWO", @"THREE", @"THREE" }

我如何将其变成

{ @"ONE", @"TWO", @"THREE" }

..数组遵循与原始数据相同的顺序。我认为您可以将数组转换为NSSet以获取唯一的项目,但如果您将其转换回数组,则无法保证获得相同的顺序..

5 个答案:

答案 0 :(得分:49)

我最初的想法是你能做到:

NSArray * a = [NSArray arrayWithObjects:@"ONE", @"ONE", @"ONE", @"TWO", @"THREE", @"THREE", nil];
NSLog(@"%@", [a valueForKeyPath:@"@distinctUnionOfObjects.self"]);

但这并没有维持秩序。因此,您必须手动执行此操作:

NSArray * a = [NSArray arrayWithObjects:@"ONE", @"ONE", @"ONE", @"TWO", @"THREE", @"THREE", nil];
NSMutableArray * unique = [NSMutableArray array];
NSMutableSet * processed = [NSMutableSet set];
for (NSString * string in a) {
  if ([processed containsObject:string] == NO) {
    [unique addObject:string];
    [processed addObject:string];
  }
}

我使用NSMutableSet来确定我之前是否已经遇到此条目(而不是[unique containsObject:string],因为一个集合将具有O(1)查找时间,并且数组具有O (n)查找时间。如果你只处理少量的对象,那么这无关紧要。但是,如果源数组非常大,那么使用该集来确定唯一性可能会增加一点速度提升。(但是,您应该使用Instruments来分析您的代码并查看是否有必要)

答案 1 :(得分:47)

你可以这样做:

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

这样,您也可以保留订单!

答案 2 :(得分:6)

我认为你可以用那个

来做到这一点
NSArray * uniqueArray = [[Yourarray valueForKeyPath:@"@distinctUnionOfObjects.self"] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];

我希望这会对你有所帮助

答案 3 :(得分:0)

嗯..你可以使用循环吗?

NSMutableArray *newarray = [[NSMutableArray alloc] init];
NSString *laststring = nil;
for (NSString *currentstring in oldarray) 
{
   if (![currentstring isEqualtoString:laststring]) [newarray addObject:currentstring];
   laststring = currentstring
}

答案 4 :(得分:0)

这是一个很好的类别,它定义了custom operator之类的@distinctUnionOfObjects,但它仅适用于字符串,并且会保留其原始顺序。注意:它不会为您排序字符串。它只保留完整的任何字符串重复的第一个实例。

用法:

#import "NSArray+orderedDistinctUnionOfStrings.h"
...
// if you feed it an array that has already been ordered, it will work as expected
NSArray *myArray = @[@"ONE", @"ONE", @"ONE", @"TWO", @"THREE", @"THREE"];
NSArray *myUniqueArray = [myArray valueForKeyPath:@"@orderedDistinctUnionOfStrings.self"];

输出:

myUniqueArray = ( "ONE", "TWO", "THREE" )

.h文件:

#import <Foundation/Foundation.h>

@interface NSArray (orderedDistinctUnionOfStrings)

@end

.m文件:

#import "NSArray+orderedDistinctUnionOfObjects.h"

@implementation NSArray (orderedDistinctUnionOfObjects)

- (id) _orderedDistinctUnionOfStringsForKeyPath:(NSString*)keyPath {
    NSMutableIndexSet *removeIndexes = [NSMutableIndexSet indexSet];

    for (NSUInteger i = 0, n = self.count; i < n; ++i) {
        if ([removeIndexes containsIndex:i]) {
            continue;
        }
        NSString *str1 = [[self objectAtIndex:i] valueForKeyPath:keyPath];

        for (NSUInteger j = i+1; j < n; ++j) {
            if ([removeIndexes containsIndex:j]) {
                continue;
            }
            id obj = [self objectAtIndex:j];
            NSString *str2 = [obj valueForKeyPath:keyPath];
            if ([str1 isEqualToString:str2]) {
                [removeIndexes addIndex:j];
            }
        }
    }

    NSMutableArray *myMutableCopy = [self mutableCopy];
    [myMutableCopy removeObjectsAtIndexes:removeIndexes];

    return [[NSArray arrayWithArray:myMutableCopy] valueForKeyPath:[NSString stringWithFormat:@"@unionOfObjects.%@", keyPath]];
}

@end

以下是关于如何生成自己的运算符的优秀读物,并且(通过一点点)揭示其工作原理:http://bou.io/KVCCustomOperators.html