How to turn an NSArray of strings into an array of unique strings, in the same order?

前端 未结 5 2023
我在风中等你
我在风中等你 2020-12-23 17:34

If you have an NSArray of strings

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

How would I turn that into

<         


        
5条回答
  •  不知归路
    2020-12-23 17:55

    Here's a nice category that defines a custom operator like @distinctUnionOfObjects, except it only works on strings and it will maintain their original order. Note: It does not sort the strings for you. It leaves intact only the first instance of whatever strings are repeated.

    Usage:

    #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"];
    

    Output:

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

    .h file:

    #import 
    
    @interface NSArray (orderedDistinctUnionOfStrings)
    
    @end
    

    .m file:

    #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
    

    And here is an excellent read on how to generate your own operators, and demystifies (by a little bit) how this works: http://bou.io/KVCCustomOperators.html

提交回复
热议问题