Skip to content

Commit d5d6980

Browse files
dkosasihbenlesh
authored andcommitted
feat(partition): partition static function. partition operator is deprecated (ReactiveX#4419) (ReactiveX#4685)
1 parent b5a2ac9 commit d5d6980

File tree

7 files changed

+124
-56
lines changed

7 files changed

+124
-56
lines changed

package-lock.json

+9-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { of, partition } from 'rxjs';
2+
3+
it('should infer correctly', () => {
4+
const o = partition(of('a', 'b', 'c'), (value, index) => true); // $ExpectType [Observable<string>, Observable<string>]
5+
const p = partition(of('a', 'b', 'c'), () => true); // $ExpectType [Observable<string>, Observable<string>]
6+
});
7+
8+
it('should accept a thisArg parameter', () => {
9+
const o = partition(of('a', 'b', 'c'), () => true, 5); // $ExpectType [Observable<string>, Observable<string>]
10+
});
11+
12+
it('should enforce predicate', () => {
13+
const o = partition(of('a', 'b', 'c')); // $ExpectError
14+
});
15+
16+
it('should enforce predicate types', () => {
17+
const o = partition(of('a', 'b', 'c'), 'nope'); // $ExpectError
18+
const p = partition(of('a', 'b', 'c'), (value: number) => true); // $ExpectError
19+
const q = partition(of('a', 'b', 'c'), (value, index: string) => true); // $ExpectError
20+
});

spec-dtslint/operators/partition-spec.ts.disabled

-24
This file was deleted.

spec/operators/partition-spec.ts.disabled spec/observables/partition-spec.ts

+24-28
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
import { expect } from 'chai';
2-
import * as Rx from 'rxjs/Rx';
2+
import { Observable, partition, of } from 'rxjs';
3+
import { map, mergeMap } from 'rxjs/operators';
34
import { hot, cold, expectObservable, expectSubscriptions } from '../helpers/marble-testing';
45

5-
// TODO: The imports on these tests can't be modernized until we do away with
6-
// the partition "operator" and make it a creation method.
76
declare function asDiagram(arg: string): Function;
87

9-
const Observable = Rx.Observable;
10-
118
/** @test {partition} */
129
describe('Observable.prototype.partition', () => {
13-
function expectObservableArray(result: Rx.Observable<string>[], expected: string[]) {
10+
function expectObservableArray(result: Observable<string>[], expected: string[]) {
1411
for (let idx = 0; idx < result.length; idx++ ) {
1512
expectObservable(result[idx]).toBe(expected[idx]);
1613
}
@@ -23,7 +20,7 @@ describe('Observable.prototype.partition', () => {
2320
const expected = ['--1-----3---------5------|',
2421
'----2----------4------6--|'];
2522

26-
const result = e1.partition((x: any) => x % 2 === 1);
23+
const result = partition(e1, (x: any) => x % 2 === 1);
2724

2825
expectObservableArray(result, expected);
2926
expectSubscriptions(e1.subscriptions).toBe([e1subs, e1subs]);
@@ -39,7 +36,7 @@ describe('Observable.prototype.partition', () => {
3936
return x === 'a';
4037
}
4138

42-
expectObservableArray(e1.partition(predicate), expected);
39+
expectObservableArray(partition(e1, predicate), expected);
4340
expectSubscriptions(e1.subscriptions).toBe([e1subs, e1subs]);
4441
});
4542

@@ -53,7 +50,7 @@ describe('Observable.prototype.partition', () => {
5350
return index % 2 === 0;
5451
}
5552

56-
expectObservableArray(e1.partition(predicate), expected);
53+
expectObservableArray(partition(e1, predicate), expected);
5754
expectSubscriptions(e1.subscriptions).toBe([e1subs, e1subs]);
5855
});
5956

@@ -67,7 +64,7 @@ describe('Observable.prototype.partition', () => {
6764
return x === this.value;
6865
}
6966

70-
expectObservableArray(e1.partition(predicate, {value: 'a'}), expected);
67+
expectObservableArray(partition(e1, predicate, {value: 'a'}), expected);
7168
expectSubscriptions(e1.subscriptions).toBe([e1subs, e1subs]);
7269
});
7370

@@ -81,7 +78,7 @@ describe('Observable.prototype.partition', () => {
8178
return x === 'a';
8279
}
8380

84-
expectObservableArray(e1.partition(predicate), expected);
81+
expectObservableArray(partition(e1, predicate), expected);
8582
expectSubscriptions(e1.subscriptions).toBe([e1subs, e1subs]);
8683
});
8784

@@ -95,7 +92,7 @@ describe('Observable.prototype.partition', () => {
9592
return x === 'a';
9693
}
9794

98-
expectObservableArray(e1.partition(predicate), expected);
95+
expectObservableArray(partition(e1, predicate), expected);
9996
expectSubscriptions(e1.subscriptions).toBe([e1subs, e1subs]);
10097
});
10198

@@ -115,7 +112,7 @@ describe('Observable.prototype.partition', () => {
115112
return match;
116113
}
117114

118-
expectObservableArray(e1.partition(predicate), expected);
115+
expectObservableArray(partition(e1, predicate), expected);
119116
expectSubscriptions(e1.subscriptions).toBe([e1subs, e1subs]);
120117
});
121118

@@ -129,7 +126,7 @@ describe('Observable.prototype.partition', () => {
129126
return x === 'x';
130127
}
131128

132-
expectObservableArray(e1.partition(predicate), expected);
129+
expectObservableArray(partition(e1, predicate), expected);
133130
expectSubscriptions(e1.subscriptions).toBe([e1subs, e1subs]);
134131
});
135132

@@ -143,7 +140,7 @@ describe('Observable.prototype.partition', () => {
143140
return x === 'x';
144141
}
145142

146-
expectObservableArray(e1.partition(predicate), expected);
143+
expectObservableArray(partition(e1, predicate), expected);
147144
expectSubscriptions(e1.subscriptions).toBe([e1subs, e1subs]);
148145
});
149146

@@ -157,7 +154,7 @@ describe('Observable.prototype.partition', () => {
157154
return x === 'a';
158155
}
159156

160-
expectObservableArray(e1.partition(predicate), expected);
157+
expectObservableArray(partition(e1, predicate), expected);
161158
expectSubscriptions(e1.subscriptions).toBe([e1subs, e1subs]);
162159
});
163160

@@ -171,7 +168,7 @@ describe('Observable.prototype.partition', () => {
171168
return x === 'a';
172169
}
173170

174-
expectObservableArray(e1.partition(predicate), expected);
171+
expectObservableArray(partition(e1, predicate), expected);
175172
expectSubscriptions(e1.subscriptions).toBe([e1subs, e1subs]);
176173
});
177174

@@ -185,7 +182,7 @@ describe('Observable.prototype.partition', () => {
185182
return x === 'a';
186183
}
187184

188-
expectObservableArray(e1.partition(predicate), expected);
185+
expectObservableArray(partition(e1, predicate), expected);
189186
expectSubscriptions(e1.subscriptions).toBe([e1subs, e1subs]);
190187
});
191188

@@ -199,7 +196,7 @@ describe('Observable.prototype.partition', () => {
199196
return x === 'a';
200197
}
201198

202-
expectObservableArray(e1.partition(predicate), expected);
199+
expectObservableArray(partition(e1, predicate), expected);
203200
expectSubscriptions(e1.subscriptions).toBe([e1subs, e1subs]);
204201
});
205202

@@ -213,7 +210,7 @@ describe('Observable.prototype.partition', () => {
213210
return x === 'a';
214211
}
215212

216-
expectObservableArray(e1.partition(predicate), expected);
213+
expectObservableArray(partition(e1, predicate), expected);
217214
expectSubscriptions(e1.subscriptions).toBe([e1subs, e1subs]);
218215
});
219216

@@ -227,7 +224,7 @@ describe('Observable.prototype.partition', () => {
227224
function predicate(x: string) {
228225
return x === 'a';
229226
}
230-
const result = e1.partition(predicate);
227+
const result = partition(e1, predicate);
231228

232229
for (let idx = 0; idx < result.length; idx++ ) {
233230
expectObservable(result[idx], unsub).toBe(expected[idx]);
@@ -242,11 +239,10 @@ describe('Observable.prototype.partition', () => {
242239
'----b--- '];
243240
const unsub = ' ! ';
244241

245-
const result = e1
246-
.mergeMap((x: string) => Observable.of(x))
247-
.partition((x: string) => x === 'a')
248-
.map((observable: Rx.Observable<string>) =>
249-
observable.mergeMap((x: string) => Observable.of(x)));
242+
const e1Pipe = e1.pipe(
243+
mergeMap((x: string) => of(x))
244+
);
245+
const result = partition(e1Pipe, (x: string) => x === 'a');
250246

251247
expectObservable(result[0], unsub).toBe(expected[0]);
252248
expectObservable(result[1], unsub).toBe(expected[1]);
@@ -256,10 +252,10 @@ describe('Observable.prototype.partition', () => {
256252
it('should accept thisArg', () => {
257253
const thisArg = {};
258254

259-
Observable.of(1).partition(function (this: any, value: number) {
255+
partition(of(1), function (this: any, value: number) {
260256
expect(this).to.deep.equal(thisArg);
261257
return true;
262258
}, thisArg)
263-
.forEach((observable: Rx.Observable<number>) => observable.subscribe());
259+
.forEach((observable: Observable<number>) => observable.subscribe());
264260
});
265261
});

src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export { never } from './internal/observable/never';
5858
export { of } from './internal/observable/of';
5959
export { onErrorResumeNext } from './internal/observable/onErrorResumeNext';
6060
export { pairs } from './internal/observable/pairs';
61+
export { partition } from './internal/observable/partition';
6162
export { race } from './internal/observable/race';
6263
export { range } from './internal/observable/range';
6364
export { throwError } from './internal/observable/throwError';

src/internal/observable/partition.ts

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import { not } from '../util/not';
2+
import { subscribeTo } from '../util/subscribeTo';
3+
import { filter } from '../operators/filter';
4+
import { ObservableInput } from '../types';
5+
import { Observable } from '../Observable';
6+
7+
/**
8+
* Splits the source Observable into two, one with values that satisfy a
9+
* predicate, and another with values that don't satisfy the predicate.
10+
*
11+
* <span class="informal">It's like {@link filter}, but returns two Observables:
12+
* one like the output of {@link filter}, and the other with values that did not
13+
* pass the condition.</span>
14+
*
15+
* ![](partition.png)
16+
*
17+
* `partition` outputs an array with two Observables that partition the values
18+
* from the source Observable through the given `predicate` function. The first
19+
* Observable in that array emits source values for which the predicate argument
20+
* returns true. The second Observable emits source values for which the
21+
* predicate returns false. The first behaves like {@link filter} and the second
22+
* behaves like {@link filter} with the predicate negated.
23+
*
24+
* ## Example
25+
* Partition a set of numbers into odds and evens observables
26+
* ```ts
27+
* import { of, partition } from 'rxjs';
28+
*
29+
* const observableValues = of(1, 2, 3, 4, 5, 6);
30+
* const [evens$, odds$] = partition(observableValues, (value, index) => value % 2 === 0);
31+
*
32+
* odds$.subscribe(x => console.log('odds', x));
33+
* evens$.subscribe(x => console.log('evens', x));
34+
*
35+
* // Logs:
36+
* // odds 1
37+
* // odds 3
38+
* // odds 5
39+
* // evens 2
40+
* // evens 4
41+
* // evens 6
42+
* ```
43+
*
44+
* @see {@link filter}
45+
*
46+
* @param {function(value: T, index: number): boolean} predicate A function that
47+
* evaluates each value emitted by the source Observable. If it returns `true`,
48+
* the value is emitted on the first Observable in the returned array, if
49+
* `false` the value is emitted on the second Observable in the array. The
50+
* `index` parameter is the number `i` for the i-th source emission that has
51+
* happened since the subscription, starting from the number `0`.
52+
* @param {any} [thisArg] An optional argument to determine the value of `this`
53+
* in the `predicate` function.
54+
* @return {[Observable<T>, Observable<T>]} An array with two Observables: one
55+
* with values that passed the predicate, and another with values that did not
56+
* pass the predicate.
57+
*/
58+
export function partition<T>(
59+
source: ObservableInput<T>,
60+
predicate: (value: T, index: number) => boolean,
61+
thisArg?: any
62+
): [Observable<T>, Observable<T>] {
63+
return [
64+
filter(predicate, thisArg)(new Observable<T>(subscribeTo(source))),
65+
filter(not(predicate, thisArg) as any)(new Observable<T>(subscribeTo(source)))
66+
] as [Observable<T>, Observable<T>];
67+
}

src/internal/operators/partition.ts

+3
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ import { UnaryFunction } from '../types';
5050
* @method partition
5151
* @owner Observable
5252
*/
53+
/**
54+
* @deprecated use `partition` static creation function instead
55+
*/
5356
export function partition<T>(predicate: (value: T, index: number) => boolean,
5457
thisArg?: any): UnaryFunction<Observable<T>, [Observable<T>, Observable<T>]> {
5558
return (source: Observable<T>) => [

0 commit comments

Comments
 (0)