高阶变换

高阶总是给人一种十分复杂的感觉,然而在实际的使用中掌握它是有很大好处的。高阶数组是指代数组中每个元素也是数组的数组,所以高阶节点就是指代节点的值也是节点的节点。EZRNode<EZRNode *>就是一个这样的节点。下面会介绍高阶变换形式。

flatten

扁平变换就是把EZRNode<EZRNode<T> *>扁平到EZRNode<T>的一种变换,它将下游节点始终连接到上游节点的值上,例如:

  1. EZRMutableNode<NSNumber *> *nodeA = [EZRMutableNode new];
  2. EZRMutableNode<NSNumber *> *nodeB = [EZRMutableNode new];
  3. EZRMutableNode<NSNumber *> *nodeC = [EZRMutableNode new];
  4. EZRMutableNode<EZRNode<NSNumber *> *> *highOrderNode = [EZRMutableNode new];
  5. EZRNode<NSNumber *> *flattenedNode = [highOrderNode flatten];
  6. highOrderNode.value = nodeA;
  7. nodeA.value = @1;
  8. flattenedNode.value; // <- @1
  9. highOrderNode.value = nodeB;
  10. nodeB.value = @2;
  11. flattenedNode.value; // <- @2
  12. nodeA.value = @3;
  13. flattenedNode.value; // <- @2,不再受 node A 影响了
  14. highOrderNode.value = nodeC;
  15. nodeC.value = @4;
  16. flattenedNode.value; // <- @4

flattenMap

扁平映射变换相当于这样的一系列操作,它先将节点进行映射变换,并且映射的结果统统都是节点,最后再扁平变换一次。为什么我们需要扁平映射变换而不是简单的映射变换呢?是因为映射变换一定是一一对应的,假设上游节点有 10 个值的变化,映射变换后的下游节点一定也有 10 个值的变化。但如果我有 8 个或者 12 个值想要变换呢?那就需要扁平映射变换了;还有映射变换一定都是立即变换的,如果我们需要结果延迟变换,我们也需要扁平映射变换。例如下面的例子:

```objective-c
EZRMutableNode node = [EZRMutableNode new];
EZRNode<NSNumber
> flattenMappedNode = [node flattenMap:^EZRNode _Nullable(NSNumber _Nullable next) {
NSInteger value = next.integerValue;
EZRMutableNode<NSNumber
> insideNode = [EZRMutableNode new];
EZRNode<NSNumber
> returnNode = [insideNode deliverOnMainQueue];
while(value != 0) {
insideNode.value = @(value % 10);
value /= 10;
}
return returnNode;
}];
[[flattenMappedNode listenedBy:self] withBlock:^(NSNumber
_Nullable next) {
NSLog(@”FlattenMappedNode 收到了 %@”, next);
}];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
node.value = @12;
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2
NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
node.value = @0;
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
node.value = @27;
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4
NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
node.value = @9527;
});
/ 打印如下:
FlattenMappedNode 收到了 2
FlattenMappedNode 收到了 1
FlattenMappedNode 收到了 7
FlattenMappedNode 收到了 2
FlattenMappedNode 收到了 7
FlattenMappedNode 收到了 2
FlattenMappedNode 收到了 5
FlattenMappedNode 收到了 9
/