我有一个对象数组,我将其转换为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]];
}];
如果您只需要NSSet
或NSArray
或其子类类型集合中对象的一个属性的值,您可以使用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];