NSArray/NSSet集合中对象属性的投影



我有一个对象数组,我将其转换为NSSet:

NSArray *arr = @[@{ @"someProp": @21, @"unnecessaryProp": @"tada" }, ... ];
NSSet *collection = [NSSet setWithArray:arr];

我想把我想要的属性(按键)从集合中的每个对象中投影出来,并以一个新的数组结束,如:

NSArray *projectedArray = [collection allObjects]; // @[@{ "someProp": @21 }, ... ], "unnecessaryProp" has been removed

除了枚举,还有其他的方法吗,比如NSPredicate ?

: 数组中的对象是NSObject的子类,在我的例子中我提到了NSDictionary

由于NSPredicate不做投影,您最终将枚举集合。我将用一个块枚举它,并像这样在各个字典中投影键:

NSArray *keep= @["someProp"];
NSMutableArray *res = [NSMutableArray array];
[collection enumerateObjectsUsingBlock:^(id dict, BOOL *stop) {
    NSArray *values = [dict objectsForKeys:keep notFoundMarker:@""];
    [res addObject:[NSDictionary dictionaryWithObjects:values forKeys:keep]];
}];

EDIT:(回复评论)

我应该提到过,数组中的对象是NSObject的子类,objectsForKeys不是一个方法。

那么你可以使用MartinR的建议使用KVC构建一个字典:

NSArray *keep= @["someProp"];
NSMutableArray *res = [NSMutableArray array];
[collection enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
    [res addObject:[obj dictionaryWithValuesForKeys:keep]];
}];

如果您只需要NSSetNSArray或其子类类型集合中对象的一个属性的值,您可以使用KVC方法valueForKey:

NSArray *dogs = @[@{@"name" : @"Fido",
                @"toys" : @[@"Ball", @"Kong"]},
                @{@"name" : @"Rover",
                @"toys" : @[@"Ball", @"Rope"]},
                @{@"name" : @"Spot",
                @"toys" : @[@"Rope", @"Kong"]}];
NSArray *vals = [set valueForKey:@"name"];
NSLog(@"%@", vals);

上面的代码在控制台上打印如下内容:

2014-05-16 09:26:58.293 xctest[17223:303] (
    Fido,
    Rover,
    Spot
)

如果需要集合中对象的多个属性值,使用dictionaryWithValuesForKeys:。给定与上一个示例相同的数组,下面的代码…

NSDictionary *dict = [dogs dictionaryWithValuesForKeys:@[@"name", @"toys"]];
NSLog(@"%@", dict);

生成字典数组,并记录以下输出:

2014-05-16 09:35:34.793 xctest[17275:303] {
    name =     (
        Fido,
        Rover,
        Spot
    );
    toys =     (
                (
            Ball,
            Kong
        ),
                (
            Ball,
            Rope
        ),
                (
            Rope,
            Kong
        )
    );
}

不管目标集合中的对象是NSDictionary的实例还是自定义类的实例,

您可以在数组或NSSet上使用indexOfObjectPassingTest。

__block NSUInteger  maxIdex = [_myArrray count]-1;
__block NSMutableIndexSet* objToRemove = [[NSMutableIndexSet alloc]init];
    [_myArrray indexOfObjectPassingTest:^(id object, NSUInteger idx, BOOL * stop){
        MyObject *obj = (MyObject*)object;
        if(....){
            [objToRemove addIndex:[_myArrray indexOfObject:obj]];
        }
        *stop = (idx == maxIdex);
        return *stop;
    }];
 [_myArrray removeObjectsAtIndexes:objToRemove];

最新更新