[Object-c]_[初级]_[数组NSArray过滤NSPredicate的简单介绍]

本文对比了Objective-C中NSPredicate与C++中std::find_if的使用方法,通过具体示例展示了如何利用这两种方式实现数组中对象的筛选及查询,包括字符串匹配、子对象查询、大小写不敏感查询等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

场景

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

# 参考

Predicate Programming Guide
NSPredicate

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白行微

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值