Skip to content
This repository was archived by the owner on Apr 20, 2018. It is now read-only.

Commit c9885f7

Browse files
committed
Change pluck to accept nested properties
1 parent 037234d commit c9885f7

File tree

3 files changed

+114
-7
lines changed

3 files changed

+114
-7
lines changed

doc/api/core/operators/pluck.md

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
### `Rx.Observable.prototype.pluck(property)`
2-
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/pluck.js "View in source")
2+
[Ⓢ](https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/pluck.js#L10 "View in source")
33

4-
Projects each element of an observable sequence into a new form by incorporating the element's index.
4+
Returns an Observable containing the value of a specified nested property from
5+
all elements in the Observable sequence. If a property can't be resolved, it
6+
will return `undefined` for that value.
57

68
#### Arguments
7-
1. `property` *(`String`)*: The property to pluck.
9+
1. `property` *(`String`)*: The property or properties to pluck. `pluck`
10+
accepts an unlimited number of nested property parameters.
811

912
#### Returns
1013
*(`Observable`)*: Returns a new Observable sequence of property values.
@@ -34,6 +37,32 @@ var subscription = source.subscribe(
3437
// => Next: 1
3538
// => Next: 2
3639
// => Completed
40+
41+
// Using nested properties:
42+
43+
var source = Rx.Observable
44+
.from([
45+
{ valueA: { valueB: { valueC: 0 }}},
46+
{ valueA: { valueB: { valueC: 1 }}},
47+
{ valueA: { valueB: 2 }},
48+
])
49+
.pluck('valueA', 'valueB', 'valueC');
50+
51+
var subscription = source.subscribe(
52+
function (x) {
53+
console.log('Next: ' + x);
54+
},
55+
function (err) {
56+
console.log('Error: ' + err);
57+
},
58+
function () {
59+
console.log('Completed');
60+
});
61+
62+
// => Next: 0
63+
// => Next: 1
64+
// => Next: undefined
65+
// => Completed
3766
```
3867

3968
### Location

src/core/linq/observable/pluck.js

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,26 @@
11
/**
2-
* Retrieves the value of a specified property from all elements in the Observable sequence.
3-
* @param {String} prop The property to pluck.
2+
* Retrieves the value of a specified nested property from all elements in
3+
* the Observable sequence.
4+
* @param {String} nestedProps The nested property to pluck.
45
* @returns {Observable} Returns a new Observable sequence of property values.
56
*/
6-
observableProto.pluck = function (prop) {
7-
return this.map(function (x) { return x[prop]; });
7+
observableProto.pluck = function () {
8+
var args = [].slice.call(arguments);
9+
var len = args.length;
10+
return this.map(function (x) {
11+
if (len === 0) {
12+
return undefined;
13+
}
14+
15+
var currentProp = x;
16+
for (var i = 0; i < len; i++) {
17+
var p = currentProp[args[i]];
18+
if (typeof p !== 'undefined') {
19+
currentProp = p;
20+
} else {
21+
return undefined;
22+
}
23+
}
24+
return currentProp;
25+
});
826
};

tests/observable/pluck.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,63 @@ test('Pluck_Completed', function () {
4040

4141
xs.subscriptions.assertEqual(subscribe(200, 400));
4242
});
43+
44+
test('Deep_Pluck_Nested_Completed', function () {
45+
var scheduler = new TestScheduler();
46+
47+
var xs = scheduler.createHotObservable(
48+
onNext(180, {a: {b: {c: 1}}}),
49+
onNext(210, {a: {b: {c: 2}}}),
50+
onNext(240, {a: {b: {c: 3}}}),
51+
onNext(290, {a: {b: {c: 4}}}),
52+
onNext(350, {a: {b: {c: 5}}}),
53+
onCompleted(400),
54+
onNext(410, {a: {b: {c: -1}}}),
55+
onCompleted(420),
56+
onError(430, new Error('ex'))
57+
);
58+
59+
var results = scheduler.startWithCreate(function () {
60+
return xs.pluck('a', 'b', 'c');
61+
});
62+
63+
results.messages.assertEqual(
64+
onNext(210, 2),
65+
onNext(240, 3),
66+
onNext(290, 4),
67+
onNext(350, 5),
68+
onCompleted(400)
69+
);
70+
71+
xs.subscriptions.assertEqual(subscribe(200, 400));
72+
});
73+
74+
test('Deep_Pluck_Nested_Edgecases', function () {
75+
var scheduler = new TestScheduler();
76+
77+
var xs = scheduler.createHotObservable(
78+
onNext(180, {a: {b: {c: 1}}}),
79+
onNext(210, {a: {b: 2}}),
80+
onNext(240, {a: {c: {c: 3}}}),
81+
onNext(290, {}),
82+
onNext(350, {a: {b: {c: 5}}}),
83+
onCompleted(400),
84+
onNext(410, {a: {b: {c: -1}}}),
85+
onCompleted(420),
86+
onError(430, new Error('ex'))
87+
);
88+
89+
var results = scheduler.startWithCreate(function () {
90+
return xs.pluck('a', 'b', 'c');
91+
});
92+
93+
results.messages.assertEqual(
94+
onNext(210, undefined),
95+
onNext(240, undefined),
96+
onNext(290, undefined),
97+
onNext(350, 5),
98+
onCompleted(400)
99+
);
100+
101+
xs.subscriptions.assertEqual(subscribe(200, 400));
102+
});

0 commit comments

Comments
 (0)