分支

优质
小牛编辑
129浏览
2023-12-01

分支变换与组合变换恰好相反,它通常是由一个上游节点以特定的规则分离出不同的下游节点。下面是全部的分支变换形式。

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
 */