如何使用 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】:

试试你的predicatematches 关键字,它会给你精确的结果匹配,因此你可以删除谓词中的重复出现,如下所示-

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 从数组中选择确切的短语?的主要内容,如果未能解决你的问题,请参考以下文章

使用 NSPredicate 仅从字典数组中获取特定键的值

NSPredicate IN 从数组元素中查询

使用 Realm 和 NSPredicate 按数组索引排序

您可以使用 NSPredicate 指定“从...中选择唯一名称”吗?

使用 NSPredicate 在单个搜索 iOS swift 中搜索多个单词

如何使用 NSPredicate 加快数组搜索速度?