在 iOS 中的字典中使用字典数组的 NSPredicate 进行过滤
Filter using NSPredicate of Array of Dictionary within dictionary in iOS
Rewards -- Array
Normal Reward -- Object
Offer -- Dictionary
Meta -- Dictionary
rewardId -- String
Normal Reward -- Object
Offer -- Dictionary
Meta -- Dictionary
rewardId -- String
我有上面的层次结构,我必须从中匹配一个特定的 rewardId 作为一个值。我怎样才能使用 NSPredicate 来实现。
这个谓词应该可以解决问题:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.nameOfOfferProperty.nameOfMetaKey.nameOfRewardIdKey == %@", myRewardIdToMatch]
我根据您的需要明确命名了要走的路径。
使用示例代码(这样您可以在需要时查看要使用的名称):
NSMutableArray *rewards = [[NSMutableArray alloc] init];
for (NSUInteger i = 0; i < 10; i ++)
{
NSString *rewardId = [NSString stringWithFormat:@"rewardID %@", (i%2 == 0)?@"Target":@"NonWanted"];
NSString *otherMetaValue = [NSString stringWithFormat:@"otherMetaValue-%ld", i];
NSString *otherOfferValue = [NSString stringWithFormat:@"otherOfferValue-%ld", i];
NSDictionary *anOfferDict = @{@"meta": @{@"rewardId": rewardId,
@"otherMetaKey": otherMetaValue},
@"otherOfferKey": otherOfferValue};
Reward *aReward = [[Reward alloc] initWithOfferDict:anOfferDict andIntValue:i];
[rewards addObject:aReward];
}
NSLog(@"Rewards: %@", rewards);
NSString * myRewardIdToMatch = @"rewardID Target";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.offer.meta.rewardId == %@", myRewardIdToMatch];
NSArray *filteredRewards = [rewards filteredArrayUsingPredicate:predicate];
NSLog(@"FilteredRewards: %@", filteredRewards);
和
@implementation Reward
-(id)initWithOfferDict:(NSDictionary *)dict andIntValue:(NSUInteger)intV
{
self = [super init];
if (self)
{
_offer = dict;
_intV = intV;
}
return self;
}
覆盖 description
可能会有所帮助,并明确说明它是否有效:
-(NSString *)description
{
return [NSString stringWithFormat:@"<%@ %p> with IntValue: %ld and rewardID:\n%@", [self class], self, _intV, _offer[@"meta"][@"rewardId"]];
}
@end
输出:
$> Rewards: (
"<Reward 0x60000022ce80> with IntValue: 0 and rewardID: rewardID Target",
"<Reward 0x60000022ce00> with IntValue: 1 and rewardID: rewardID NonWanted",
"<Reward 0x60000022cf80> with IntValue: 2 and rewardID: rewardID Target",
"<Reward 0x60000022cea0> with IntValue: 3 and rewardID: rewardID NonWanted",
"<Reward 0x60000022cf20> with IntValue: 4 and rewardID: rewardID Target",
"<Reward 0x60000022ce40> with IntValue: 5 and rewardID: rewardID NonWanted",
"<Reward 0x60000022cfa0> with IntValue: 6 and rewardID: rewardID Target",
"<Reward 0x60000022cfc0> with IntValue: 7 and rewardID: rewardID NonWanted",
"<Reward 0x60000022ce60> with IntValue: 8 and rewardID: rewardID Target",
"<Reward 0x60000022cec0> with IntValue: 9 and rewardID: rewardID NonWanted"
)
$> FilteredRewards: (
"<Reward 0x60000022ce80> with IntValue: 0 and rewardID: rewardID Target",
"<Reward 0x60000022cf80> with IntValue: 2 and rewardID: rewardID Target",
"<Reward 0x60000022cf20> with IntValue: 4 and rewardID: rewardID Target",
"<Reward 0x60000022cfa0> with IntValue: 6 and rewardID: rewardID Target",
"<Reward 0x60000022ce60> with IntValue: 8 and rewardID: rewardID Target"
)
Rewards -- Array
Normal Reward -- Object
Offer -- Dictionary
Meta -- Dictionary
rewardId -- String
Normal Reward -- Object
Offer -- Dictionary
Meta -- Dictionary
rewardId -- String
我有上面的层次结构,我必须从中匹配一个特定的 rewardId 作为一个值。我怎样才能使用 NSPredicate 来实现。
这个谓词应该可以解决问题:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.nameOfOfferProperty.nameOfMetaKey.nameOfRewardIdKey == %@", myRewardIdToMatch]
我根据您的需要明确命名了要走的路径。
使用示例代码(这样您可以在需要时查看要使用的名称):
NSMutableArray *rewards = [[NSMutableArray alloc] init];
for (NSUInteger i = 0; i < 10; i ++)
{
NSString *rewardId = [NSString stringWithFormat:@"rewardID %@", (i%2 == 0)?@"Target":@"NonWanted"];
NSString *otherMetaValue = [NSString stringWithFormat:@"otherMetaValue-%ld", i];
NSString *otherOfferValue = [NSString stringWithFormat:@"otherOfferValue-%ld", i];
NSDictionary *anOfferDict = @{@"meta": @{@"rewardId": rewardId,
@"otherMetaKey": otherMetaValue},
@"otherOfferKey": otherOfferValue};
Reward *aReward = [[Reward alloc] initWithOfferDict:anOfferDict andIntValue:i];
[rewards addObject:aReward];
}
NSLog(@"Rewards: %@", rewards);
NSString * myRewardIdToMatch = @"rewardID Target";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.offer.meta.rewardId == %@", myRewardIdToMatch];
NSArray *filteredRewards = [rewards filteredArrayUsingPredicate:predicate];
NSLog(@"FilteredRewards: %@", filteredRewards);
和
@implementation Reward
-(id)initWithOfferDict:(NSDictionary *)dict andIntValue:(NSUInteger)intV
{
self = [super init];
if (self)
{
_offer = dict;
_intV = intV;
}
return self;
}
覆盖 description
可能会有所帮助,并明确说明它是否有效:
-(NSString *)description
{
return [NSString stringWithFormat:@"<%@ %p> with IntValue: %ld and rewardID:\n%@", [self class], self, _intV, _offer[@"meta"][@"rewardId"]];
}
@end
输出:
$> Rewards: (
"<Reward 0x60000022ce80> with IntValue: 0 and rewardID: rewardID Target",
"<Reward 0x60000022ce00> with IntValue: 1 and rewardID: rewardID NonWanted",
"<Reward 0x60000022cf80> with IntValue: 2 and rewardID: rewardID Target",
"<Reward 0x60000022cea0> with IntValue: 3 and rewardID: rewardID NonWanted",
"<Reward 0x60000022cf20> with IntValue: 4 and rewardID: rewardID Target",
"<Reward 0x60000022ce40> with IntValue: 5 and rewardID: rewardID NonWanted",
"<Reward 0x60000022cfa0> with IntValue: 6 and rewardID: rewardID Target",
"<Reward 0x60000022cfc0> with IntValue: 7 and rewardID: rewardID NonWanted",
"<Reward 0x60000022ce60> with IntValue: 8 and rewardID: rewardID Target",
"<Reward 0x60000022cec0> with IntValue: 9 and rewardID: rewardID NonWanted"
)
$> FilteredRewards: (
"<Reward 0x60000022ce80> with IntValue: 0 and rewardID: rewardID Target",
"<Reward 0x60000022cf80> with IntValue: 2 and rewardID: rewardID Target",
"<Reward 0x60000022cf20> with IntValue: 4 and rewardID: rewardID Target",
"<Reward 0x60000022cfa0> with IntValue: 6 and rewardID: rewardID Target",
"<Reward 0x60000022ce60> with IntValue: 8 and rewardID: rewardID Target"
)