分支
分支变换与组合变换恰好相反,它通常是由一个上游节点以特定的规则分离出不同的下游节点。下面是全部的分支变换形式。
switch-case-default
switch-case-default 变换是通过给出的 block 将每个上游的值代入,求出唯一标识符,再分离这些标识符的一种操作。我们举例一个分离剧本的例子:
EZRMutableNode<NSString *> *node = [EZRMutableNode new];
EZRNode<EZRSwitchedNodeTuple<NSString *> *> *nodes = [node switch:^id<NSCopying> _Nonnull(NSString * _Nullable next) {
NSArray<NSString *> *components = [next componentsSeparatedByString:@":"];
return components.count > 1 ? components.firstObject: nil;
}];
EZRNode<NSString *> *liLeiSaid = [nodes case:@"李雷"];
EZRNode<NSString *> *hanMeimeiSaid = [nodes case:@"韩梅梅"];
EZRNode<NSString *> *aside = [nodes default];
[[liLeiSaid listenedBy:self] withBlock:^(NSString *next) {
NSLog(@"李雷节点接到台词: %@", next);
}];
[[hanMeimeiSaid listenedBy:self] withBlock:^(NSString *next) {
NSLog(@"韩梅梅节点接到台词: %@", next);
}];
[[aside listenedBy:self] withBlock:^(NSString *next) {
NSLog(@"旁白节点接到台词: %@", next);
}];
node.value = @"在一个宁静的下午";
node.value = @"李雷:大家好,我叫李雷。";
node.value = @"韩梅梅:大家好,我叫韩梅梅。";
node.value = @"李雷:你好韩梅梅。";
node.value = @"韩梅梅:你好李雷。";
node.value = @"于是他们幸福的在一起了";
/* 打印如下:
旁白节点接到台词: 在一个宁静的下午
李雷节点接到台词: 李雷:大家好,我叫李雷。
韩梅梅节点接到台词: 韩梅梅:大家好,我叫韩梅梅。
李雷节点接到台词: 李雷:你好韩梅梅。
韩梅梅节点接到台词: 韩梅梅:你好李雷。
旁白节点接到台词: 于是他们幸福的在一起了
*/
我们注意到,“李雷节点接到台词: 李雷:大家好,我叫李雷。”这个分支里面所有的值还包含“李雷”这个部分,这显然是不必要的,所以我们可能需要在拆分的过程中修改原始的内容,switchMap-case-default 就可以很好的解决了:
EZRMutableNode<NSString *> *node = [EZRMutableNode new];
// 只需要改下面这里
EZRNode<EZRSwitchedNodeTuple<id> *> *nodes = [node switchMap:^EZTuple2<id<NSCopying>,id> * _Nonnull(NSString * _Nullable next) {
NSArray<NSString *> *components = [next componentsSeparatedByString:@":"];
if (components.count > 1) {
NSString *actorLines = [next substringFromIndex:components.firstObject.length + 1];
return EZTuple(components.firstObject, actorLines);
} else {
return EZTuple(nil, next);
}
}];
EZRNode<NSString *> *liLeiSaid = [nodes case:@"李雷"];
EZRNode<NSString *> *hanMeimeiSaid = [nodes case:@"韩梅梅"];
EZRNode<NSString *> *aside = [nodes default];
[[liLeiSaid listenedBy:self] withBlock:^(NSString *next) {
NSLog(@"李雷节点接到台词: %@", next);
}];
[[hanMeimeiSaid listenedBy:self] withBlock:^(NSString *next) {
NSLog(@"韩梅梅节点接到台词: %@", next);
}];
[[aside listenedBy:self] withBlock:^(NSString *next) {
NSLog(@"旁白节点接到台词: %@", next);
}];
node.value = @"在一个宁静的下午";
node.value = @"李雷:大家好,我叫李雷。";
node.value = @"韩梅梅:大家好,我叫韩梅梅。";
node.value = @"李雷:你好韩梅梅。";
node.value = @"韩梅梅:你好李雷。";
node.value = @"于是他们幸福的在一起了";
/* 打印如下:
旁白节点接到台词: 在一个宁静的下午
李雷节点接到台词: 大家好,我叫李雷。
韩梅梅节点接到台词: 大家好,我叫韩梅梅。
李雷节点接到台词: 你好韩梅梅。
韩梅梅节点接到台词: 你好李雷。
旁白节点接到台词: 于是他们幸福的在一起了
*/
if-then-else
有的时候,你可能只想要区分是否,并不需要太多的分支,这时 if-then-else 刚好满足需要:
EZRMutableNode<NSNumber *> *node = [EZRMutableNode new];
[[[node if:^BOOL(NSNumber *next) {
return next.integerValue > 0;
}] then:^(EZRNode *node) {
[[node listenedBy:self] withBlock:^(NSNumber *next) {
NSLog(@"符合条件的有:%@", next);
}];
}] else:^(EZRNode *node) {
[[node listenedBy:self] withBlock:^(NSNumber *next) {
NSLog(@"不符合条件的有:%@", next);
}];
}];
node.value = @1;
node.value = @-1;
node.value = @2;
node.value = @0;
node.value = @-3;
/* 打印如下:
符合条件的有:1
不符合条件的有:-1
符合条件的有:2
不符合条件的有:0
不符合条件的有:-3
*/
如果想直接拿到是或否两个分支节点,直接使用 if 的返回值EZRIFResult
就可以了:
EZRMutableNode<NSNumber *> *node = [EZRMutableNode new];
EZRIFResult *result = [node if:^BOOL(NSNumber *next) {
return next.integerValue > 0;
}];
EZRNode<NSNumber *> *positiveNode = result.thenNode;
[[positiveNode listenedBy:self] withBlock:^(NSNumber *next) {
NSLog(@"正数的有:%@", next);
}];
node.value = @1;
node.value = @-1;
node.value = @2;
node.value = @0;
node.value = @-3;
/* 打印如下:
正数的有:1
正数的有:2
*/