|
499 | 499 | };
|
500 | 500 |
|
501 | 501 | /**
|
502 |
| - * Returns the element at a specified index in a sequence or undefined if not found. |
503 |
| - * @example |
504 |
| - * var res = source.elementAt(5); |
| 502 | + * Returns the element at a specified index in a sequence or default value if not found. |
505 | 503 | * @param {Number} index The zero-based index of the element to retrieve.
|
| 504 | + * @param {Any} [defaultValue] The default value to use if elementAt does not find a value. |
506 | 505 | * @returns {Observable} An observable sequence that produces the element at the specified position in the source sequence.
|
507 | 506 | */
|
508 |
| - observableProto.elementAt = function (index) { |
| 507 | + observableProto.elementAt = function (index, defaultValue) { |
509 | 508 | if (index < 0) { throw new ArgumentOutOfRangeError(); }
|
510 | 509 | var source = this;
|
511 | 510 | return new AnonymousObservable(function (o) {
|
512 | 511 | var i = index;
|
513 |
| - return source.subscribe(function (x) { |
514 |
| - if (i-- === 0) { |
515 |
| - o.onNext(x); |
516 |
| - o.onCompleted(); |
517 |
| - } |
518 |
| - }, function (e) { o.onError(e); }, function () { |
519 |
| - o.onNext(undefined); |
520 |
| - o.onCompleted(); |
| 512 | + return source.subscribe( |
| 513 | + function (x) { |
| 514 | + if (i-- === 0) { |
| 515 | + o.onNext(x); |
| 516 | + o.onCompleted(); |
| 517 | + } |
| 518 | + }, |
| 519 | + function (e) { o.onError(e); }, |
| 520 | + function () { |
| 521 | + if (defaultValue === undefined) { |
| 522 | + o.onError(new ArgumentOutOfRangeError()); |
| 523 | + } else { |
| 524 | + o.onNext(defaultValue); |
| 525 | + o.onCompleted(); |
| 526 | + } |
521 | 527 | });
|
522 | 528 | }, source);
|
523 | 529 | };
|
|
549 | 555 |
|
550 | 556 | /**
|
551 | 557 | * Returns the first element of an observable sequence that satisfies the condition in the predicate if present else the first item in the sequence.
|
552 |
| - * @param {Function} [predicate] A predicate function to evaluate for elements in the source sequence. |
553 |
| - * @param {Any} [thisArg] Object to use as `this` when executing the predicate. |
554 | 558 | * @returns {Observable} Sequence containing the first element in the observable sequence that satisfies the condition in the predicate if provided, else the first item in the sequence.
|
555 | 559 | */
|
556 |
| - observableProto.first = function (predicate, thisArg, defaultValue) { |
557 |
| - if (isFunction(predicate)) { return this.filter(predicate, thisArg).first(defaultValue); } |
558 |
| - var source = this; |
| 560 | + observableProto.first = function () { |
| 561 | + var obj = {}, source = this; |
| 562 | + if (typeof arguments[0] === 'object') { |
| 563 | + obj = arguments[0]; |
| 564 | + } else { |
| 565 | + obj = { |
| 566 | + predicate: arguments[0], |
| 567 | + thisArg: arguments[1], |
| 568 | + defaultValue: arguments[2] |
| 569 | + }; |
| 570 | + } |
| 571 | + if (isFunction (obj.predicate)) { |
| 572 | + var fn = obj.predicate; |
| 573 | + obj.predicate = bindCallback(fn, obj.thisArg, 3); |
| 574 | + } |
559 | 575 | return new AnonymousObservable(function (o) {
|
560 |
| - return source.subscribe(function (x) { |
561 |
| - o.onNext(x); |
562 |
| - o.onCompleted(); |
563 |
| - }, function (e) { o.onError(e); }, function () { |
564 |
| - o.onNext(defaultValue); |
565 |
| - o.onCompleted(); |
566 |
| - }); |
| 576 | + var i = 0; |
| 577 | + return source.subscribe( |
| 578 | + function (x) { |
| 579 | + if (obj.predicate) { |
| 580 | + var res = tryCatch(obj.predicate)(x, i++, source); |
| 581 | + if (res === errorObj) { return o.onError(res.e); } |
| 582 | + if (res) { |
| 583 | + o.onNext(x); |
| 584 | + o.onCompleted(); |
| 585 | + } |
| 586 | + } else if (!obj.predicate) { |
| 587 | + o.onNext(x); |
| 588 | + o.onCompleted(); |
| 589 | + } |
| 590 | + }, |
| 591 | + function (e) { o.onError(e); }, |
| 592 | + function () { |
| 593 | + if (obj.defaultValue === undefined) { |
| 594 | + o.onError(new EmptyError()); |
| 595 | + } else { |
| 596 | + o.onNext(obj.defaultValue); |
| 597 | + o.onCompleted(); |
| 598 | + } |
| 599 | + }); |
567 | 600 | }, source);
|
568 | 601 | };
|
569 | 602 |
|
570 | 603 | /**
|
571 | 604 | * Returns the last element of an observable sequence that satisfies the condition in the predicate if specified, else the last element.
|
572 |
| - * @param {Function} [predicate] A predicate function to evaluate for elements in the source sequence. |
573 |
| - * @param {Any} [thisArg] Object to use as `this` when executing the predicate. |
574 | 605 | * @returns {Observable} Sequence containing the last element in the observable sequence that satisfies the condition in the predicate.
|
575 | 606 | */
|
576 |
| - observableProto.last = function (predicate, thisArg) { |
577 |
| - if (isFunction(predicate)) { return this.filter(predicate, thisArg).last(); } |
578 |
| - var source = this; |
| 607 | + observableProto.last = function () { |
| 608 | + var obj = {}, source = this; |
| 609 | + if (typeof arguments[0] === 'object') { |
| 610 | + obj = arguments[0]; |
| 611 | + } else { |
| 612 | + obj = { |
| 613 | + predicate: arguments[0], |
| 614 | + thisArg: arguments[1], |
| 615 | + defaultValue: arguments[2] |
| 616 | + }; |
| 617 | + } |
| 618 | + if (isFunction (obj.predicate)) { |
| 619 | + var fn = obj.predicate; |
| 620 | + obj.predicate = bindCallback(fn, obj.thisArg, 3); |
| 621 | + } |
579 | 622 | return new AnonymousObservable(function (o) {
|
580 |
| - var value, seenValue = false; |
581 |
| - return source.subscribe(function (x) { |
582 |
| - value = x; |
583 |
| - }, function (e) { o.onError(e); }, function () { |
584 |
| - o.onNext(value); |
585 |
| - o.onCompleted(); |
586 |
| - }); |
| 623 | + var value, seenValue = false, i = 0; |
| 624 | + return source.subscribe( |
| 625 | + function (x) { |
| 626 | + if (obj.predicate) { |
| 627 | + var res = tryCatch(obj.predicate)(x, i++, source); |
| 628 | + if (res === errorObj) { return o.onError(res.e); } |
| 629 | + if (res) { |
| 630 | + seenValue = true; |
| 631 | + value = x; |
| 632 | + } |
| 633 | + } else if (!obj.predicate) { |
| 634 | + seenValue = true; |
| 635 | + value = x; |
| 636 | + } |
| 637 | + }, |
| 638 | + function (e) { o.onError(e); }, |
| 639 | + function () { |
| 640 | + if (seenValue) { |
| 641 | + o.onNext(value); |
| 642 | + o.onCompleted(); |
| 643 | + } |
| 644 | + else if (obj.defaultValue === undefined) { |
| 645 | + o.onError(new EmptyError()); |
| 646 | + } else { |
| 647 | + o.onNext(obj.defaultValue); |
| 648 | + o.onCompleted(); |
| 649 | + } |
| 650 | + }); |
587 | 651 | }, source);
|
588 | 652 | };
|
589 | 653 |
|
|
0 commit comments