Skip to content
This repository was archived by the owner on Dec 5, 2019. It is now read-only.

Commit e94a432

Browse files
committed
Merge pull request ReactiveCocoa#1638 from ReactiveCocoa/combining-conveniences
Add combineLatest() and zip() over multiple signals
2 parents 67f98f7 + 2daee11 commit e94a432

File tree

4 files changed

+274
-0
lines changed

4 files changed

+274
-0
lines changed

ReactiveCocoa.xcodeproj/project.pbxproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
/* Begin PBXBuildFile section */
1010
270DE4451A1EAB4600151031 /* ObservablePropertySpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 277F6A951A1EAA10003E0EC9 /* ObservablePropertySpec.swift */; };
1111
270DE4461A1EACA200151031 /* ObservablePropertySpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 277F6A951A1EAA10003E0EC9 /* ObservablePropertySpec.swift */; };
12+
D00004091A46864E000E7D41 /* TupleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00004081A46864E000E7D41 /* TupleExtensions.swift */; };
13+
D000040A1A46864E000E7D41 /* TupleExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00004081A46864E000E7D41 /* TupleExtensions.swift */; };
1214
D01792021A34D79100A7B229 /* ColdSignalSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01792011A34D79100A7B229 /* ColdSignalSpec.swift */; };
1315
D01792031A34D79100A7B229 /* ColdSignalSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01792011A34D79100A7B229 /* ColdSignalSpec.swift */; };
1416
D01B7B6219EDD8FE00D26E01 /* Nimble.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = D05E662419EDD82000904ACA /* Nimble.framework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
@@ -474,6 +476,7 @@
474476

475477
/* Begin PBXFileReference section */
476478
277F6A951A1EAA10003E0EC9 /* ObservablePropertySpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObservablePropertySpec.swift; sourceTree = "<group>"; };
479+
D00004081A46864E000E7D41 /* TupleExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TupleExtensions.swift; sourceTree = "<group>"; };
477480
D01792011A34D79100A7B229 /* ColdSignalSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColdSignalSpec.swift; sourceTree = "<group>"; };
478481
D037642A19EDA41200A782A9 /* NSArray+RACSequenceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+RACSequenceAdditions.h"; sourceTree = "<group>"; };
479482
D037642B19EDA41200A782A9 /* NSArray+RACSequenceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+RACSequenceAdditions.m"; sourceTree = "<group>"; };
@@ -1116,6 +1119,7 @@
11161119
D0C312BB19EF2A5800984962 /* Atomic.swift */,
11171120
D0C312BC19EF2A5800984962 /* Bag.swift */,
11181121
D0C312C519EF2A5800984962 /* OptionalExtensions.swift */,
1122+
D00004081A46864E000E7D41 /* TupleExtensions.swift */,
11191123
);
11201124
name = "Internal Utilities";
11211125
sourceTree = "<group>";
@@ -1588,6 +1592,7 @@
15881592
D03765C819EDA41200A782A9 /* RACScopedDisposable.m in Sources */,
15891593
D03764FE19EDA41200A782A9 /* NSEnumerator+RACSequenceAdditions.m in Sources */,
15901594
D03764EA19EDA41200A782A9 /* NSArray+RACSequenceAdditions.m in Sources */,
1595+
D00004091A46864E000E7D41 /* TupleExtensions.swift in Sources */,
15911596
D0C312E119EF2A5800984962 /* OptionalExtensions.swift in Sources */,
15921597
D03765C019EDA41200A782A9 /* RACScheduler.m in Sources */,
15931598
D0C312D519EF2A5800984962 /* Errors.swift in Sources */,
@@ -1792,6 +1797,7 @@
17921797
D03B4A3E19F4C39A009E02AC /* FoundationExtensions.swift in Sources */,
17931798
D037657519EDA41200A782A9 /* RACDynamicSequence.m in Sources */,
17941799
D037657119EDA41200A782A9 /* RACDisposable.m in Sources */,
1800+
D000040A1A46864E000E7D41 /* TupleExtensions.swift in Sources */,
17951801
D03765DB19EDA41200A782A9 /* RACSignalProvider.d in Sources */,
17961802
D037653319EDA41200A782A9 /* NSSet+RACSequenceAdditions.m in Sources */,
17971803
D037665319EDA41200A782A9 /* UISwitch+RACSignalSupport.m in Sources */,

ReactiveCocoa/Swift/ColdSignal.swift

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,114 @@ extension ColdSignal {
998998
}
999999
}
10001000

1001+
/// An overloaded function that combines the values of up to 10 signals, in the
1002+
/// manner described by ColdSignal.combineLatestWith().
1003+
public func combineLatest<A, B>(a: ColdSignal<A>, b: ColdSignal<B>) -> ColdSignal<(A, B)> {
1004+
return a.combineLatestWith(b)
1005+
}
1006+
1007+
public func combineLatest<A, B, C>(a: ColdSignal<A>, b: ColdSignal<B>, c: ColdSignal<C>) -> ColdSignal<(A, B, C)> {
1008+
return combineLatest(a, b)
1009+
.combineLatestWith(c)
1010+
.map(repack)
1011+
}
1012+
1013+
public func combineLatest<A, B, C, D>(a: ColdSignal<A>, b: ColdSignal<B>, c: ColdSignal<C>, d: ColdSignal<D>) -> ColdSignal<(A, B, C, D)> {
1014+
return combineLatest(a, b, c)
1015+
.combineLatestWith(d)
1016+
.map(repack)
1017+
}
1018+
1019+
public func combineLatest<A, B, C, D, E>(a: ColdSignal<A>, b: ColdSignal<B>, c: ColdSignal<C>, d: ColdSignal<D>, e: ColdSignal<E>) -> ColdSignal<(A, B, C, D, E)> {
1020+
return combineLatest(a, b, c, d)
1021+
.combineLatestWith(e)
1022+
.map(repack)
1023+
}
1024+
1025+
public func combineLatest<A, B, C, D, E, F>(a: ColdSignal<A>, b: ColdSignal<B>, c: ColdSignal<C>, d: ColdSignal<D>, e: ColdSignal<E>, f: ColdSignal<F>) -> ColdSignal<(A, B, C, D, E, F)> {
1026+
return combineLatest(a, b, c, d, e)
1027+
.combineLatestWith(f)
1028+
.map(repack)
1029+
}
1030+
1031+
public func combineLatest<A, B, C, D, E, F, G>(a: ColdSignal<A>, b: ColdSignal<B>, c: ColdSignal<C>, d: ColdSignal<D>, e: ColdSignal<E>, f: ColdSignal<F>, g: ColdSignal<G>) -> ColdSignal<(A, B, C, D, E, F, G)> {
1032+
return combineLatest(a, b, c, d, e, f)
1033+
.combineLatestWith(g)
1034+
.map(repack)
1035+
}
1036+
1037+
public func combineLatest<A, B, C, D, E, F, G, H>(a: ColdSignal<A>, b: ColdSignal<B>, c: ColdSignal<C>, d: ColdSignal<D>, e: ColdSignal<E>, f: ColdSignal<F>, g: ColdSignal<G>, h: ColdSignal<H>) -> ColdSignal<(A, B, C, D, E, F, G, H)> {
1038+
return combineLatest(a, b, c, d, e, f, g)
1039+
.combineLatestWith(h)
1040+
.map(repack)
1041+
}
1042+
1043+
public func combineLatest<A, B, C, D, E, F, G, H, I>(a: ColdSignal<A>, b: ColdSignal<B>, c: ColdSignal<C>, d: ColdSignal<D>, e: ColdSignal<E>, f: ColdSignal<F>, g: ColdSignal<G>, h: ColdSignal<H>, i: ColdSignal<I>) -> ColdSignal<(A, B, C, D, E, F, G, H, I)> {
1044+
return combineLatest(a, b, c, d, e, f, g, h)
1045+
.combineLatestWith(i)
1046+
.map(repack)
1047+
}
1048+
1049+
public func combineLatest<A, B, C, D, E, F, G, H, I, J>(a: ColdSignal<A>, b: ColdSignal<B>, c: ColdSignal<C>, d: ColdSignal<D>, e: ColdSignal<E>, f: ColdSignal<F>, g: ColdSignal<G>, h: ColdSignal<H>, i: ColdSignal<I>, j: ColdSignal<J>) -> ColdSignal<(A, B, C, D, E, F, G, H, I, J)> {
1050+
return combineLatest(a, b, c, d, e, f, g, h, i)
1051+
.combineLatestWith(j)
1052+
.map(repack)
1053+
}
1054+
1055+
/// An overloaded function that zips the values of up to 10 signals, in the
1056+
/// manner described by ColdSignal.zipWith().
1057+
public func zip<A, B>(a: ColdSignal<A>, b: ColdSignal<B>) -> ColdSignal<(A, B)> {
1058+
return a.zipWith(b)
1059+
}
1060+
1061+
public func zip<A, B, C>(a: ColdSignal<A>, b: ColdSignal<B>, c: ColdSignal<C>) -> ColdSignal<(A, B, C)> {
1062+
return zip(a, b)
1063+
.zipWith(c)
1064+
.map(repack)
1065+
}
1066+
1067+
public func zip<A, B, C, D>(a: ColdSignal<A>, b: ColdSignal<B>, c: ColdSignal<C>, d: ColdSignal<D>) -> ColdSignal<(A, B, C, D)> {
1068+
return zip(a, b, c)
1069+
.zipWith(d)
1070+
.map(repack)
1071+
}
1072+
1073+
public func zip<A, B, C, D, E>(a: ColdSignal<A>, b: ColdSignal<B>, c: ColdSignal<C>, d: ColdSignal<D>, e: ColdSignal<E>) -> ColdSignal<(A, B, C, D, E)> {
1074+
return zip(a, b, c, d)
1075+
.zipWith(e)
1076+
.map(repack)
1077+
}
1078+
1079+
public func zip<A, B, C, D, E, F>(a: ColdSignal<A>, b: ColdSignal<B>, c: ColdSignal<C>, d: ColdSignal<D>, e: ColdSignal<E>, f: ColdSignal<F>) -> ColdSignal<(A, B, C, D, E, F)> {
1080+
return zip(a, b, c, d, e)
1081+
.zipWith(f)
1082+
.map(repack)
1083+
}
1084+
1085+
public func zip<A, B, C, D, E, F, G>(a: ColdSignal<A>, b: ColdSignal<B>, c: ColdSignal<C>, d: ColdSignal<D>, e: ColdSignal<E>, f: ColdSignal<F>, g: ColdSignal<G>) -> ColdSignal<(A, B, C, D, E, F, G)> {
1086+
return zip(a, b, c, d, e, f)
1087+
.zipWith(g)
1088+
.map(repack)
1089+
}
1090+
1091+
public func zip<A, B, C, D, E, F, G, H>(a: ColdSignal<A>, b: ColdSignal<B>, c: ColdSignal<C>, d: ColdSignal<D>, e: ColdSignal<E>, f: ColdSignal<F>, g: ColdSignal<G>, h: ColdSignal<H>) -> ColdSignal<(A, B, C, D, E, F, G, H)> {
1092+
return zip(a, b, c, d, e, f, g)
1093+
.zipWith(h)
1094+
.map(repack)
1095+
}
1096+
1097+
public func zip<A, B, C, D, E, F, G, H, I>(a: ColdSignal<A>, b: ColdSignal<B>, c: ColdSignal<C>, d: ColdSignal<D>, e: ColdSignal<E>, f: ColdSignal<F>, g: ColdSignal<G>, h: ColdSignal<H>, i: ColdSignal<I>) -> ColdSignal<(A, B, C, D, E, F, G, H, I)> {
1098+
return zip(a, b, c, d, e, f, g, h)
1099+
.zipWith(i)
1100+
.map(repack)
1101+
}
1102+
1103+
public func zip<A, B, C, D, E, F, G, H, I, J>(a: ColdSignal<A>, b: ColdSignal<B>, c: ColdSignal<C>, d: ColdSignal<D>, e: ColdSignal<E>, f: ColdSignal<F>, g: ColdSignal<G>, h: ColdSignal<H>, i: ColdSignal<I>, j: ColdSignal<J>) -> ColdSignal<(A, B, C, D, E, F, G, H, I, J)> {
1104+
return zip(a, b, c, d, e, f, g, h, i)
1105+
.zipWith(j)
1106+
.map(repack)
1107+
}
1108+
10011109
/// Blocking methods for receiving values.
10021110
extension ColdSignal {
10031111
/// Starts the receiver, then returns the first value received.

ReactiveCocoa/Swift/HotSignal.swift

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,114 @@ extension HotSignal {
640640
}
641641
}
642642

643+
/// An overloaded function that combines the values of up to 10 signals, in the
644+
/// manner described by HotSignal.combineLatestWith().
645+
public func combineLatest<A, B>(a: HotSignal<A>, b: HotSignal<B>) -> HotSignal<(A, B)> {
646+
return a.combineLatestWith(b)
647+
}
648+
649+
public func combineLatest<A, B, C>(a: HotSignal<A>, b: HotSignal<B>, c: HotSignal<C>) -> HotSignal<(A, B, C)> {
650+
return combineLatest(a, b)
651+
.combineLatestWith(c)
652+
.map(repack)
653+
}
654+
655+
public func combineLatest<A, B, C, D>(a: HotSignal<A>, b: HotSignal<B>, c: HotSignal<C>, d: HotSignal<D>) -> HotSignal<(A, B, C, D)> {
656+
return combineLatest(a, b, c)
657+
.combineLatestWith(d)
658+
.map(repack)
659+
}
660+
661+
public func combineLatest<A, B, C, D, E>(a: HotSignal<A>, b: HotSignal<B>, c: HotSignal<C>, d: HotSignal<D>, e: HotSignal<E>) -> HotSignal<(A, B, C, D, E)> {
662+
return combineLatest(a, b, c, d)
663+
.combineLatestWith(e)
664+
.map(repack)
665+
}
666+
667+
public func combineLatest<A, B, C, D, E, F>(a: HotSignal<A>, b: HotSignal<B>, c: HotSignal<C>, d: HotSignal<D>, e: HotSignal<E>, f: HotSignal<F>) -> HotSignal<(A, B, C, D, E, F)> {
668+
return combineLatest(a, b, c, d, e)
669+
.combineLatestWith(f)
670+
.map(repack)
671+
}
672+
673+
public func combineLatest<A, B, C, D, E, F, G>(a: HotSignal<A>, b: HotSignal<B>, c: HotSignal<C>, d: HotSignal<D>, e: HotSignal<E>, f: HotSignal<F>, g: HotSignal<G>) -> HotSignal<(A, B, C, D, E, F, G)> {
674+
return combineLatest(a, b, c, d, e, f)
675+
.combineLatestWith(g)
676+
.map(repack)
677+
}
678+
679+
public func combineLatest<A, B, C, D, E, F, G, H>(a: HotSignal<A>, b: HotSignal<B>, c: HotSignal<C>, d: HotSignal<D>, e: HotSignal<E>, f: HotSignal<F>, g: HotSignal<G>, h: HotSignal<H>) -> HotSignal<(A, B, C, D, E, F, G, H)> {
680+
return combineLatest(a, b, c, d, e, f, g)
681+
.combineLatestWith(h)
682+
.map(repack)
683+
}
684+
685+
public func combineLatest<A, B, C, D, E, F, G, H, I>(a: HotSignal<A>, b: HotSignal<B>, c: HotSignal<C>, d: HotSignal<D>, e: HotSignal<E>, f: HotSignal<F>, g: HotSignal<G>, h: HotSignal<H>, i: HotSignal<I>) -> HotSignal<(A, B, C, D, E, F, G, H, I)> {
686+
return combineLatest(a, b, c, d, e, f, g, h)
687+
.combineLatestWith(i)
688+
.map(repack)
689+
}
690+
691+
public func combineLatest<A, B, C, D, E, F, G, H, I, J>(a: HotSignal<A>, b: HotSignal<B>, c: HotSignal<C>, d: HotSignal<D>, e: HotSignal<E>, f: HotSignal<F>, g: HotSignal<G>, h: HotSignal<H>, i: HotSignal<I>, j: HotSignal<J>) -> HotSignal<(A, B, C, D, E, F, G, H, I, J)> {
692+
return combineLatest(a, b, c, d, e, f, g, h, i)
693+
.combineLatestWith(j)
694+
.map(repack)
695+
}
696+
697+
/// An overloaded function that zips the values of up to 10 signals, in the
698+
/// manner described by HotSignal.zipWith().
699+
public func zip<A, B>(a: HotSignal<A>, b: HotSignal<B>) -> HotSignal<(A, B)> {
700+
return a.zipWith(b)
701+
}
702+
703+
public func zip<A, B, C>(a: HotSignal<A>, b: HotSignal<B>, c: HotSignal<C>) -> HotSignal<(A, B, C)> {
704+
return zip(a, b)
705+
.zipWith(c)
706+
.map(repack)
707+
}
708+
709+
public func zip<A, B, C, D>(a: HotSignal<A>, b: HotSignal<B>, c: HotSignal<C>, d: HotSignal<D>) -> HotSignal<(A, B, C, D)> {
710+
return zip(a, b, c)
711+
.zipWith(d)
712+
.map(repack)
713+
}
714+
715+
public func zip<A, B, C, D, E>(a: HotSignal<A>, b: HotSignal<B>, c: HotSignal<C>, d: HotSignal<D>, e: HotSignal<E>) -> HotSignal<(A, B, C, D, E)> {
716+
return zip(a, b, c, d)
717+
.zipWith(e)
718+
.map(repack)
719+
}
720+
721+
public func zip<A, B, C, D, E, F>(a: HotSignal<A>, b: HotSignal<B>, c: HotSignal<C>, d: HotSignal<D>, e: HotSignal<E>, f: HotSignal<F>) -> HotSignal<(A, B, C, D, E, F)> {
722+
return zip(a, b, c, d, e)
723+
.zipWith(f)
724+
.map(repack)
725+
}
726+
727+
public func zip<A, B, C, D, E, F, G>(a: HotSignal<A>, b: HotSignal<B>, c: HotSignal<C>, d: HotSignal<D>, e: HotSignal<E>, f: HotSignal<F>, g: HotSignal<G>) -> HotSignal<(A, B, C, D, E, F, G)> {
728+
return zip(a, b, c, d, e, f)
729+
.zipWith(g)
730+
.map(repack)
731+
}
732+
733+
public func zip<A, B, C, D, E, F, G, H>(a: HotSignal<A>, b: HotSignal<B>, c: HotSignal<C>, d: HotSignal<D>, e: HotSignal<E>, f: HotSignal<F>, g: HotSignal<G>, h: HotSignal<H>) -> HotSignal<(A, B, C, D, E, F, G, H)> {
734+
return zip(a, b, c, d, e, f, g)
735+
.zipWith(h)
736+
.map(repack)
737+
}
738+
739+
public func zip<A, B, C, D, E, F, G, H, I>(a: HotSignal<A>, b: HotSignal<B>, c: HotSignal<C>, d: HotSignal<D>, e: HotSignal<E>, f: HotSignal<F>, g: HotSignal<G>, h: HotSignal<H>, i: HotSignal<I>) -> HotSignal<(A, B, C, D, E, F, G, H, I)> {
740+
return zip(a, b, c, d, e, f, g, h)
741+
.zipWith(i)
742+
.map(repack)
743+
}
744+
745+
public func zip<A, B, C, D, E, F, G, H, I, J>(a: HotSignal<A>, b: HotSignal<B>, c: HotSignal<C>, d: HotSignal<D>, e: HotSignal<E>, f: HotSignal<F>, g: HotSignal<G>, h: HotSignal<H>, i: HotSignal<I>, j: HotSignal<J>) -> HotSignal<(A, B, C, D, E, F, G, H, I, J)> {
746+
return zip(a, b, c, d, e, f, g, h, i)
747+
.zipWith(j)
748+
.map(repack)
749+
}
750+
643751
/// Conversions from HotSignal to ColdSignal.
644752
extension HotSignal {
645753
/// Buffers `count` values, starting at the time of the method invocation.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//
2+
// TupleExtensions.swift
3+
// ReactiveCocoa
4+
//
5+
// Created by Justin Spahr-Summers on 2014-12-20.
6+
// Copyright (c) 2014 GitHub. All rights reserved.
7+
//
8+
9+
import Foundation
10+
11+
/// Adds a value into an N-tuple, returning an (N+1)-tuple.
12+
///
13+
/// Supports creating tuples up to 10 elements long.
14+
internal func repack<A>(t: (), value: A) -> (A) {
15+
return (value)
16+
}
17+
18+
internal func repack<A, B>(t: (A), value: B) -> (A, B) {
19+
return (t.0, value)
20+
}
21+
22+
internal func repack<A, B, C>(t: (A, B), value: C) -> (A, B, C) {
23+
return (t.0, t.1, value)
24+
}
25+
26+
internal func repack<A, B, C, D>(t: (A, B, C), value: D) -> (A, B, C, D) {
27+
return (t.0, t.1, t.2, value)
28+
}
29+
30+
internal func repack<A, B, C, D, E>(t: (A, B, C, D), value: E) -> (A, B, C, D, E) {
31+
return (t.0, t.1, t.2, t.3, value)
32+
}
33+
34+
internal func repack<A, B, C, D, E, F>(t: (A, B, C, D, E), value: F) -> (A, B, C, D, E, F) {
35+
return (t.0, t.1, t.2, t.3, t.4, value)
36+
}
37+
38+
internal func repack<A, B, C, D, E, F, G>(t: (A, B, C, D, E, F), value: G) -> (A, B, C, D, E, F, G) {
39+
return (t.0, t.1, t.2, t.3, t.4, t.5, value)
40+
}
41+
42+
internal func repack<A, B, C, D, E, F, G, H>(t: (A, B, C, D, E, F, G), value: H) -> (A, B, C, D, E, F, G, H) {
43+
return (t.0, t.1, t.2, t.3, t.4, t.5, t.6, value)
44+
}
45+
46+
internal func repack<A, B, C, D, E, F, G, H, I>(t: (A, B, C, D, E, F, G, H), value: I) -> (A, B, C, D, E, F, G, H, I) {
47+
return (t.0, t.1, t.2, t.3, t.4, t.5, t.6, t.7, value)
48+
}
49+
50+
internal func repack<A, B, C, D, E, F, G, H, I, J>(t: (A, B, C, D, E, F, G, H, I), value: J) -> (A, B, C, D, E, F, G, H, I, J) {
51+
return (t.0, t.1, t.2, t.3, t.4, t.5, t.6, t.7, t.8, value)
52+
}

0 commit comments

Comments
 (0)