分支

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

switch-case-default

switch-case-default 变换是通过给出的 block 将每个上游的值代入,求出唯一标识符,再分离这些标识符的一种操作。我们举例一个分离剧本的例子:

  1. EZRMutableNode<NSString *> *node = [EZRMutableNode new];
  2. EZRNode<EZRSwitchedNodeTuple<NSString *> *> *nodes = [node switch:^id<NSCopying> _Nonnull(NSString * _Nullable next) {
  3. NSArray<NSString *> *components = [next componentsSeparatedByString:@":"];
  4. return components.count > 1 ? components.firstObject: nil;
  5. }];
  6. EZRNode<NSString *> *liLeiSaid = [nodes case:@"李雷"];
  7. EZRNode<NSString *> *hanMeimeiSaid = [nodes case:@"韩梅梅"];
  8. EZRNode<NSString *> *aside = [nodes default];
  9. [[liLeiSaid listenedBy:self] withBlock:^(NSString *next) {
  10. NSLog(@"李雷节点接到台词: %@", next);
  11. }];
  12. [[hanMeimeiSaid listenedBy:self] withBlock:^(NSString *next) {
  13. NSLog(@"韩梅梅节点接到台词: %@", next);
  14. }];
  15. [[aside listenedBy:self] withBlock:^(NSString *next) {
  16. NSLog(@"旁白节点接到台词: %@", next);
  17. }];
  18. node.value = @"在一个宁静的下午";
  19. node.value = @"李雷:大家好,我叫李雷。";
  20. node.value = @"韩梅梅:大家好,我叫韩梅梅。";
  21. node.value = @"李雷:你好韩梅梅。";
  22. node.value = @"韩梅梅:你好李雷。";
  23. node.value = @"于是他们幸福的在一起了";
  24. /* 打印如下:
  25. 旁白节点接到台词: 在一个宁静的下午
  26. 李雷节点接到台词: 李雷:大家好,我叫李雷。
  27. 韩梅梅节点接到台词: 韩梅梅:大家好,我叫韩梅梅。
  28. 李雷节点接到台词: 李雷:你好韩梅梅。
  29. 韩梅梅节点接到台词: 韩梅梅:你好李雷。
  30. 旁白节点接到台词: 于是他们幸福的在一起了
  31. */

我们注意到,“李雷节点接到台词: 李雷:大家好,我叫李雷。”这个分支里面所有的值还包含“李雷”这个部分,这显然是不必要的,所以我们可能需要在拆分的过程中修改原始的内容,switchMap-case-default 就可以很好的解决了:

  1. EZRMutableNode<NSString *> *node = [EZRMutableNode new];
  2. // 只需要改下面这里
  3. EZRNode<EZRSwitchedNodeTuple<id> *> *nodes = [node switchMap:^EZTuple2<id<NSCopying>,id> * _Nonnull(NSString * _Nullable next) {
  4. NSArray<NSString *> *components = [next componentsSeparatedByString:@":"];
  5. if (components.count > 1) {
  6. NSString *actorLines = [next substringFromIndex:components.firstObject.length + 1];
  7. return EZTuple(components.firstObject, actorLines);
  8. } else {
  9. return EZTuple(nil, next);
  10. }
  11. }];
  12. EZRNode<NSString *> *liLeiSaid = [nodes case:@"李雷"];
  13. EZRNode<NSString *> *hanMeimeiSaid = [nodes case:@"韩梅梅"];
  14. EZRNode<NSString *> *aside = [nodes default];
  15. [[liLeiSaid listenedBy:self] withBlock:^(NSString *next) {
  16. NSLog(@"李雷节点接到台词: %@", next);
  17. }];
  18. [[hanMeimeiSaid listenedBy:self] withBlock:^(NSString *next) {
  19. NSLog(@"韩梅梅节点接到台词: %@", next);
  20. }];
  21. [[aside listenedBy:self] withBlock:^(NSString *next) {
  22. NSLog(@"旁白节点接到台词: %@", next);
  23. }];
  24. node.value = @"在一个宁静的下午";
  25. node.value = @"李雷:大家好,我叫李雷。";
  26. node.value = @"韩梅梅:大家好,我叫韩梅梅。";
  27. node.value = @"李雷:你好韩梅梅。";
  28. node.value = @"韩梅梅:你好李雷。";
  29. node.value = @"于是他们幸福的在一起了";
  30. /* 打印如下:
  31. 旁白节点接到台词: 在一个宁静的下午
  32. 李雷节点接到台词: 大家好,我叫李雷。
  33. 韩梅梅节点接到台词: 大家好,我叫韩梅梅。
  34. 李雷节点接到台词: 你好韩梅梅。
  35. 韩梅梅节点接到台词: 你好李雷。
  36. 旁白节点接到台词: 于是他们幸福的在一起了
  37. */

if-then-else

有的时候,你可能只想要区分是否,并不需要太多的分支,这时 if-then-else 刚好满足需要:

  1. EZRMutableNode<NSNumber *> *node = [EZRMutableNode new];
  2. [[[node if:^BOOL(NSNumber *next) {
  3. return next.integerValue > 0;
  4. }] then:^(EZRNode *node) {
  5. [[node listenedBy:self] withBlock:^(NSNumber *next) {
  6. NSLog(@"符合条件的有:%@", next);
  7. }];
  8. }] else:^(EZRNode *node) {
  9. [[node listenedBy:self] withBlock:^(NSNumber *next) {
  10. NSLog(@"不符合条件的有:%@", next);
  11. }];
  12. }];
  13. node.value = @1;
  14. node.value = @-1;
  15. node.value = @2;
  16. node.value = @0;
  17. node.value = @-3;
  18. /* 打印如下:
  19. 符合条件的有:1
  20. 不符合条件的有:-1
  21. 符合条件的有:2
  22. 不符合条件的有:0
  23. 不符合条件的有:-3
  24. */

如果想直接拿到是或否两个分支节点,直接使用 if 的返回值EZRIFResult就可以了:

  1. EZRMutableNode<NSNumber *> *node = [EZRMutableNode new];
  2. EZRIFResult *result = [node if:^BOOL(NSNumber *next) {
  3. return next.integerValue > 0;
  4. }];
  5. EZRNode<NSNumber *> *positiveNode = result.thenNode;
  6. [[positiveNode listenedBy:self] withBlock:^(NSNumber *next) {
  7. NSLog(@"正数的有:%@", next);
  8. }];
  9. node.value = @1;
  10. node.value = @-1;
  11. node.value = @2;
  12. node.value = @0;
  13. node.value = @-3;
  14. /* 打印如下:
  15. 正数的有:1
  16. 正数的有:2
  17. */