如何使用 NSPredicate 从数组中选择确切的短语?
Posted
技术标签:
【中文标题】如何使用 NSPredicate 从数组中选择确切的短语?【英文标题】:How can I use an NSPredicate to select an exact phrase from an array? 【发布时间】:2014-06-27 21:01:29 【问题描述】:我正在使用 NSPredicate 按州和国家/地区列表过滤 NSDictionary。
所有数据都存储在一个逗号分隔的数组中:@"Alabama"、@"Alaska"、@"Arizona"、@"Arkansas"、@"California"、@"Colorado" 等
但是,有两种情况会发生重复。州“新墨西哥”包含“墨西哥”一词,“阿肯色”包含“堪萨斯”一词。
这是我用来定义谓词的基本代码。
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"Location contains[c] %@", @"Kansas"];
如何确保“Kansas”不返回带有“Arkansas”的对象? 使用 BEGINSWITH 或 LIKE 不起作用,因为列表以其他状态开始。
谢谢!
【问题讨论】:
@"Location == %@"
呢?
我刚试了一下,好像和使用BEGINSWITH或者LIKE一样。不过感谢您的想法。
“列表以其他状态开始”是什么意思?运算符 == 或 LIKE 应该选择准确的短语...
@Jonah: ==
用于精确比较,与 BEGINSWITH 或 LIKE 不同。也许您可以添加一个具体示例,其中==
无法按预期工作。如果您只有一个字符串数组,我也不清楚“位置”属性的来源。对于“==”和 LIKE 之间的区别,这可能会有所帮助:***.com/questions/14578513/nspredicate-core-data/…。
我试过了:NSPredicate *predicate = [NSPredicate predicateWithFormat:@"Location == %@", @"Kansas"];它没有返回任何结果。
【参考方案1】:
让我们看看我是否理解正确。您有一本字典,其中有一个键“Location”,其对象是一个以逗号分隔的状态名称的字符串。听起来你需要一个正则表达式来匹配。
NSString* expr = [NSString stringWithFormat:@"^%1$@.*|.*, %1$@.*", @"Kansas"]
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"Location MATCHES[c] %@", expr];
现在,这是不同示例的行为方式:
@@"Location": @"Kansas, Arkansas, Alabama" //Pass
@@"Location": @"Alabama, Kansas" //Pass
@@"Location": @"Arkansas, Alabama" //Fail
正则表达式^%1$@.*|.*, %1$@.*
测试提供的单词是在字符串的开头还是后跟字符和“,”,将其放在中间。 %1$@
采用第一个参数,因此可以多次使用它,而不是多次使用同一个字符串。
【讨论】:
你能解释一下当你用这个创建字符串时发生了什么吗? @"^%1$@.*|.*, %1$@.*" 我猜你是说“Kansas”要么是第一个对象,要么前面有一个“,”,对吗? 实际上就是这么说的。【参考方案2】:这有帮助吗?
// If I understood correctly, then your locations in the dictionary are like this
NSString *locations = @"Alabama, Alaska, Arizona, Arkansas";
NSString *trimmedLocations = [locations stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSMutableArray *compoments = [[trimmedLocations componentsSeparatedByString:@","] mutableCopy];
//now in components we have this: @[@"Alabama", @"Alaska", @"Arizona", @"Arkansas", @"California", @"Colorado"]
[compoments filterUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSString *evaluatedObject, NSDictionary *bindings)
return [evaluatedObject isEqualToString:@"Kansas"];
]];
BOOL match = compoments.count;
if (match)
//do something with locations...
【讨论】:
【参考方案3】:NSPredicate* predicate = [NSPredicate predicateWithFormat:@"Location IN %@", myStatesArray];
【讨论】:
【参考方案4】:我认为您想要的是完全匹配谓词搜索:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"Location == [c] %@", @"Kansas"];
我是不是理解错了你的问题?
【讨论】:
【参考方案5】:它会起作用的:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"entity.name LIKE[c] %@", myString];
LIKE 匹配带有 ? 的字符串和 * 作为通配符。 [c] 表示比较应该不区分大小写。
如果你不想?和 * 被视为通配符,您可以使用 == 代替 LIKE:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"entity.name ==[c] %@", myString];
NSPredicate 谓词格式字符串语法documentation 中的更多信息。
【讨论】:
【参考方案6】: NSPredicate *predicate = [NSPredicate predicateWithFormat:@"Location matches[c] %@", @"Kansas"];
这必须帮助您解决问题。
【讨论】:
【参考方案7】:试试你的predicate
和matches
关键字,它会给你精确的结果匹配,因此你可以删除谓词中的重复出现,如下所示-
NSArray *yourArr=@[@"Alabama", @"Alaska", @"Arizona", @"Arkansas", @"California", @"Colorado"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"Location contains[CD] %@", @"Kansas"];
NSMutableArray *filterdArray=[yourArr filteredArrayUsingPredicate:predicate];
if(filterdArray.count>0)
NSLog(@"Invalid State");
【讨论】:
以上是关于如何使用 NSPredicate 从数组中选择确切的短语?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Realm 和 NSPredicate 按数组索引排序
您可以使用 NSPredicate 指定“从...中选择唯一名称”吗?