场景
1.object-c的数组 NSArray 或 C++的 std::vector都支持查询特定条件的对象. NSArray内置了NSPredicate方式的查询, 可以说更加方便.
说明
1.object-c的 NSPredicate 缺点就是如果对要处理的属性值进行复杂换算再比较是做不到, 比如对属性 name 进行md5计算再比较, 不过这个时候一般都是用for进行迭代. NSPredicate 还有其他复杂的语法, 参考 Predicate Programming Guide
2.C++ 的 std::find_if 没有 NSPredicate的语法要求, 可以通过C++语法自由控制条件, 特别C++的lamda支持下更是方便, 缺点是需要一定的编码量, 比如模糊匹配和大小写不敏感查询, 区别是只查询第一个匹配的. 如果要匹配全部, 只能枚举每个元素或使用std::for_each.
例子
void TestArray(){
std::vector<UiDevice*> ca;
NSMutableArray* a = [NSMutableArray new];
NSString *str = [NSString stringWithUTF8String:"asdfasdf"];
UiDevice* d = [UiDevice new];
[d setDeviceId:str];
NSString* str2 = d.deviceId;
UiBook *book1 = [UiBook new];
[book1 setName:@"python"];
[d setBook:book1];
[d set_id:10];
[a addObject:d];
ca.push_back(d);
d = [UiDevice new];
[d setDeviceId:@"cc"];
book1 = [UiBook new];
[book1 setName:@"java"];
[d setBook:book1];
[d set_id:3];
[a addObject:d];
ca.push_back(d);
d = [UiDevice new];
[d setDeviceId:@"666"];
book1 = [UiBook new];
[book1 setName:@"java concurrent"];
[d setBook:book1];
[d set_id:6];
[a addObject:d];
ca.push_back(d);
d = [UiDevice new];
[d setDeviceId:@"777"];
[d setBook:nil];
[d set_id:6];
[a addObject:d];
ca.push_back(d);
NSLog(@"查询匹配字符串");
NSPredicate* p = [NSPredicate predicateWithFormat:@"deviceId==%@",@"cc"];
NSArray* result = [a filteredArrayUsingPredicate:p];
for (UiDevice* device in result)
NSLog(@"deviceId: %@, book.name %@",device.deviceId,device.book.name);
NSLog(@"查询子对象");
p = [NSPredicate predicateWithFormat:@"book.name==%@",@"python"];
result = [a filteredArrayUsingPredicate:p];
for (UiDevice* device in result)
NSLog(@"deviceId: %@, book.name %@",device.deviceId,device.book.name);
NSLog(@"子字符串 加[cd]大小写不敏感");
p = [NSPredicate predicateWithFormat:@"book.name contains[cd] %@",@"Ja"];
result = [a filteredArrayUsingPredicate:p];
for (UiDevice* device in result)
NSLog(@"deviceId: %@, book.name %@",device.deviceId,device.book.name);
NSLog(@"字符串模糊匹配 加[cd]大小写不敏感");
p = [NSPredicate predicateWithFormat:@"book.name like[cd] %@",@"Jav*"];
result = [a filteredArrayUsingPredicate:p];
for (UiDevice* device in result)
NSLog(@"deviceId: %@, book.name %@",device.deviceId,device.book.name);
NSLog(@"数值 AND OR");
p = [NSPredicate predicateWithFormat:@"_id >= %d OR _id == %d",10,3];
result = [a filteredArrayUsingPredicate:p];
for (UiDevice* device in result)
NSLog(@"deviceId: %@, _id %ld",device.deviceId,device._id);
NSLog(@"nil");
p = [NSPredicate predicateWithFormat:@"book == nil",10,3];
result = [a filteredArrayUsingPredicate:p];
for (UiDevice* device in result)
NSLog(@"deviceId: %@, _id %ld",device.deviceId,device._id);
NSLog(@"std::find_if查询匹配字符串");
auto ite = std::find_if(ca.begin(),ca.end(),[](UiDevice* device)->bool{
return [device.book.name compare:@"java"] == NSOrderedSame;
});
if (ite != ca.end()) {
auto device = *ite;
NSLog(@"deviceId: %@, book.name %@",device.deviceId,device.book.name);
}
}
输出
2017-07-07 17:12:51.520 TestObjc[1734:303] 查询匹配字符串
2017-07-07 17:12:51.530 TestObjc[1734:303] deviceId: cc, book.name java
2017-07-07 17:12:51.530 TestObjc[1734:303] 查询子对象
2017-07-07 17:12:51.531 TestObjc[1734:303] deviceId: asdfasdf, book.name python
2017-07-07 17:12:51.532 TestObjc[1734:303] 子字符串 加[cd]大小写不敏感
2017-07-07 17:12:51.533 TestObjc[1734:303] deviceId: cc, book.name java
2017-07-07 17:12:51.533 TestObjc[1734:303] deviceId: 666, book.name java concurrent
2017-07-07 17:12:51.534 TestObjc[1734:303] 字符串模糊匹配 加[cd]大小写不敏感
2017-07-07 17:12:51.538 TestObjc[1734:303] deviceId: cc, book.name java
2017-07-07 17:12:51.539 TestObjc[1734:303] deviceId: 666, book.name java concurrent
2017-07-07 17:12:51.539 TestObjc[1734:303] 数值 AND OR
2017-07-07 17:12:51.540 TestObjc[1734:303] deviceId: asdfasdf, _id 10
2017-07-07 17:12:51.541 TestObjc[1734:303] deviceId: cc, _id 3
2017-07-07 17:12:51.541 TestObjc[1734:303] nil
2017-07-07 17:12:51.542 TestObjc[1734:303] deviceId: 777, _id 6
2017-07-07 17:12:51.542 TestObjc[1734:303] std::find_if查询匹配字符串
2017-07-07 17:12:51.543 TestObjc[1734:303] deviceId: cc, book.name java
# 参考