这个问题已被多次询问,我已经完成了每一个解决方案,也试图实施,但没有一个适合我。
问题:使用Can't do a substring operation with something that isn't a string
过滤NSArray
时出现此错误:NSPredicate
。
编码资料:通过这种方式,我正在尝试过滤我的数组
NSArray *array = [[NSArray alloc]initWithArray:dataArray];
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"name BEGINSWITH[c] %@", searchText];
allProductData = [[array filteredArrayUsingPredicate:resultPredicate]mutableCopy]; //Error is here
现在有两个数组用于第一个数组,相同的代码不适用于第二个数组。
数组1:适用于此阵列。
(
{
"_id" = 59483833710f853221c90a92;
attributes = (
{
key = Atributos;
value = "-";
}
);
name = "Ades Soya Bebida Chocolate 946 Ml";
price = "-";
uri = "http://res.cloudinary.com/cloudimp/image/upload/u3kgmm8bx5lsmmacbnrl.jpg";
},
{
"_id" = 5948383f853221c90a94;
attributes = (
);
name = "Ades Soya Bebida Chocolate 200 Ml";
price = "";
uri = "http://res.cloudinary.com/cloudimp/image/upload/hhafrnwocqoamhhievoy.jpg";
}
)
过滤键: name = "Ades Soya Bebida Chocolate 946 Ml";
数组2:过滤器不适用于此阵列。
(
{
image = "http://images.qliktag.com/image/upload/w3tb9dutynou1hlooexn.gif";
name = Abuelita;
products = (
{
"_id" = 594c030f124244325;
attributes = (
);
name = "Abuelita chocolate granulado";
price = "";
uri = "http://images.qliktag.com/image/upload/iiqfuiilstvksdycnfbc.jpg";
},
{
"_id" = 5931c73303f737086;
attributes = (
);
name = "ABUELITA Chocolate";
price = "";
uri = "<null>";
},
{ //Crashing app for this while reading this structure.
"_id" = 5931c73303f737086;
attributes = (
);
name = (
{
language = @"en"
value = "SOYA"
},
{
language = @"de"
value = "SOYA Bebida"
}
);
price = "";
uri = "<null>";
}
);
}
注意:两个数组name
的值都不同。
最后我要过滤name
name1 = "Ades Soya Bebida Chocolate 946 Ml"
name2 = Abuelita; //Crashing app for this while filtering.
数组正在动态变化,看起来与此类似......
example-1:应用程序崩溃,出现此错误:无法对不是字符串的内容执行子字符串操作。
ContactName[0] "ABC"
ContactName[1] = XYZ
ContactName[2] = (
{
language = @"en"
value = "PQR"
},
{
language = @"de"
value = "QWERTY"
}
)
示例2:应用程序正常运行
ContactName[0] = "ABC"
ContactName[1] = "XYZ"
ContactName[2] = "PQR"
那么,我应该如何过滤这样的数组... ???
答案 0 :(得分:0)
我建议-[NSPredicate predicateWithBlock:]
。
测试product[@"name"]
的类型。如果类型为NSString
,请使用-[NSString hasPrefix:]
。如果类型为NSArray
,则找到等于NSLocale.currentLocale.languageCode
的语言,然后比较,然后在值上使用-[NSString hasPrefix:]
。
- (void)testBeginsWithSearchText {
NSArray<NSDictionary *> *data =
@[@{@"image": @"http://images.qliktag.com/image/upload/w3tb9dutynou1hlooexn.gif",
@"name": @"Abuelita",
@"products": @[@{@"_id": @"594c030f124244325",
@"attributes": @[],
@"name": @"Abuelita chocolate granulado",
@"price": @"",
@"uri": @"http://images.qliktag.com/image/upload/iiqfuiilstvksdycnfbc.jpg"},
@{@"_id": @"5931c73303f737086",
@"attributes": @[],
@"name": @"ABUELITA Chocolate",
@"price": @"",
@"uri": @"<null>"},
@{@"_id": @"5931c73303f737086",
@"attributes": @[],
@"name": @[@{@"language": @"en",
@"value": @"SOYA"},
@{@"language": @"de",
@"value": @"SOYA Bebida"}],
@"price": @"",
@"uri": @"<null>"}]}];
NSString *searchText = @"SOYA";
id beginsWithSearchText = [NSPredicate predicateWithBlock:^BOOL(NSDictionary *product, NSDictionary *bindings) {
if ([product[@"name"] isKindOfClass:[NSString class]]) {
return [product[@"name"] hasPrefix:searchText];
} else if ([product[@"name"] isKindOfClass:[NSArray class]]) {
NSUInteger index = [product[@"name"] indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
return [obj[@"language"] isEqualToString:NSLocale.currentLocale.languageCode];
}];
return index != NSNotFound && [product[@"name"][index][@"value"] hasPrefix:searchText];
} else {
return NO;
}
}];
NSArray *result = [data.firstObject[@"products"] filteredArrayUsingPredicate:beginsWithSearchText];
XCTAssertEqual(result.count, 1);
XCTAssertEqualObjects(result.firstObject[@"_id"], @"5931c73303f737086");
}