正如问题所说的那样,这是一个有效的输出,当您查看between和(A,1) (A,2) (B,1) (B,2) (C,1) (B,3) (B,4)
时,我们会发现我们需要存储每个字母的等待数。(C,1)
(B,2)
(B,3)
更重要的是,正如问题所说:
除了这些规则所规定的之外,期望事物将按照它们提交到输入的顺序到达输出。
所以在转发了一些值之后,我们可能还有一些排队的值。以问题的输出为例,我们肯定还在等待转发之后(B,4)
的到来。(B,3)
(C,1)
这是一个代码示例,RAC 部分与 Justin 的几乎相同,而我在注释中强调了不同之处:
另外,我发布了一个完整且可运行的代码示例:http ://d.pr/X59S/9p9bT58U 。
RACSubject *input = [RACSubject subject];
RACSignal *output = [[[[input
map:^(NSString *combo) {
NSArray *components = [combo componentsSeparatedByString:@","];
NSInteger number = [components[1] integerValue];
return RACTuplePack(components[0], @(number));
}]
// !!!: DIFF
// We need there state parameters:
// 1. The letters and numbers we're waiting for.
// 2. Values received that cannot be forwarded until a certain
// letter/number.
// 3. The values to forward at each step.
scanWithStart:RACTuplePack(@{ @"A": @1 }, @[], @[]) reduce:^id(RACTuple *state, RACTuple *letterAndNumber) {
__block NSDictionary *waitingLettersAndNumbers = state[0];
__block NSArray *queuedValues = state[1];
// Enqueue this value until we're ready to send it (which may or may not
// occur on this step of the scan).
queuedValues = [queuedValues arrayByAddingObject:letterAndNumber];
char letterChar = [letterAndNumber.first characterAtIndex:0];
// !!!: DIFF
// (letter + 1, number) may be a valid output after forwarding (letter, number + 1)
if (
[[waitingLettersAndNumbers objectForKey:letterAndNumber.first] isEqualToNumber:letterAndNumber.second]
&&
(letterChar == 'A' || [[waitingLettersAndNumbers objectForKey:[NSString stringWithFormat:@"%c", letterChar - 1]] integerValue] > [letterAndNumber.second integerValue])
) {
NSMutableDictionary *mutableWaitingLettersAndNumbers = [NSMutableDictionary dictionaryWithDictionary:waitingLettersAndNumbers];
// Sort queuedValues lexically and numerically.
queuedValues = ...
// Determine the next letter and number.
NSMutableArray *forwardValues = [NSMutableArray array];
NSMutableArray *remindValues = [NSMutableArray array];
[queuedValues enumerateObjectsUsingBlock:^(RACTuple *tuple, NSUInteger idx, BOOL *stop) {
...
}];
queuedValues = [remindValues copy];
waitingLettersAndNumbers = [mutableWaitingLettersAndNumbers copy];
// !!!: DIFF
// After forwarding some values, we may still have some queued values.
return RACTuplePack(waitingLettersAndNumbers, queuedValues, forwardValues);
} else {
// No values should escape the scan yet. Just pass on our queued
// values.
return RACTuplePack(waitingLettersAndNumbers, queuedValues, @[]);
}
}]
map:^(RACTuple *state) {
// Convert the array of values into a signal.
NSArray *forwardValues = state.last;
return [forwardValues.rac_sequence signalWithScheduler:[RACScheduler immediateScheduler]];
}]
// Forward values from each inner signal in the correct, sorted order.
concat];