0

Suppose I have a signal of arrays arraySignal, and a signal of objects addedObjectsSignal.

I would like to define a third signal, modifiedArraySignal, that takes the latest array from arraySignal and adds to it the objects from addedObjectsSignal sent since the latest array from arraySignal.

Here's one way to do it:

    RACSignal *modifiedArraySignal =
    [[RACSignal
     merge:@[arraySignal, addedObjectsSignal]]
     scanWithStart:@[]
     reduce:^(id running, id next) {
         if ([next isKindOfClass:[NSArray class]])
             return next;
         else
             return [running arrayByAddingObject:next];
     }];

Is there another approach that doesn't use -[NSObject isKindOfClass:]?

Tom
  • 3,831
  • 1
  • 22
  • 24

2 Answers2

2

Originally a comment, but, code formatting.

When a new array is sent, do you want updates to previous arrays to stop? In other words, if, after array B is sent, do you want both scans on array A and array B to operate simultaneously, or not? If you want updates to prior arrays to stop, use -map:/-switchToLatest instead of -flattenMap::

RACSignal *modifiedArraySignal = [[arraySignal
    map:^(NSArray *array) {
        return [[addedObjectsSignal
            scanWithStart:array reduce:^(NSArray *running, id next) {
                return [running arrayByAddingObject:next];
            }]
            startWith:array];
    }]
    switchToLatest];
Dave Lee
  • 6,299
  • 1
  • 36
  • 36
  • Nice. I just edited my own answer to give it the property of stopping updates on prior arrays, but your solution is more elegant. – Tom Aug 18 '13 at 18:19
  • Thanks. Your `-takeUntil:` approach should behave identically. – Dave Lee Aug 18 '13 at 20:13
0

I came up with a solution that I like better than the one I gave in my question, and which I think is equivalent:

RACSignal * modifiedArraySignal =
[arraySignal flattenMap:^(NSArray *array) {
    return [[[addedObjectsSignal
            takeUntil:[arraySignal skip:1]]
            scanWithStart:array
            reduce:^(NSArray *running, id next) {
                return [running arrayByAddingObject:next];
            }]
            startWith:array];
}];
Tom
  • 3,831
  • 1
  • 22
  • 24