说我事先不知道2 NSDictionaries
,如:
NSDictionary *dictA = @{ @"key1" : @1,
@"key2" : @2 };
NSDictionary *dictB = @{ @"key1" : @"a string" };
我想找到dictB
的键与dictA
的键或值之间的第一个匹配项。 dictB
的每个键都可以是NSNumber或字符串。如果是数字,请尝试从dictA
的值中找到匹配项。如果是字符串,请尝试从dictA
的键中找到匹配项。
使用for循环,它看起来像这样:
id match;
for (id key in dictA ) {
for (id _key in dictB {
if ( [_key is kindOfClass:NSNumber.class] && _key == dictA[key] ) {
match = _key
goto outer;
}
else if ( [_key is kindOfClass:NSString.class] && [_key isEqualToString:key] ) {
match = _key
goto outer;
}
}
};
outer:;
NSString *message = match ? @"A match was found" : @"No match was found";
NSLog(message);
如何使用RACSequence
和RACStream
方法使用ReactiveCocoa重写此内容,使其看起来像:
// shortened pseudo code:
// id match = [dictA.rac_sequence compare with dictB.rac_sequence using block and return first match];
答案 0 :(得分:4)
您基本上想要创建字典的笛卡尔积并对其进行选择。我知道ReactiveCocoa中没有默认运算符可以为您执行此操作。 (在LINQ中有运算符。)在RAC中,最简单的解决方案是使用scanWithStart:combine:
方法来实现此操作。一旦笛卡尔准备就绪,filter:
和take:1
操作将产生您选择的序列。
NSDictionary *adic = @{@"aa":@"vb", @"ab": @"va"};
NSDictionary *bdic = @{@"ba": @"va", @"bb":@"vb"};;
RACSequence *aseq = adic.rac_keySequence;
RACSequence *bseq = bdic.rac_keySequence;
RACSequence *cartesian = [[aseq scanWithStart:nil combine:^id(id running, id next_a) {
return [bseq scanWithStart:nil combine:^id(id running, id next_b) {
return RACTuplePack(next_a, next_b);
}];
}] flatten];
RACSequence *filteredCartesian = [cartesian filter:^BOOL(RACTuple *value) {
RACTupleUnpack(NSString *key_a, NSString *key_b) = value;
// business logic with keys
return false;
}];
RACSequence *firstMatch = [filteredCartesian take:1];