[Rx] Состояние
От: _NN_ www.nemerleweb.com
Дата: 04.11.15 10:46
Оценка:
Как правильно убрать переменную и сделать код чище ?
Мне кажется BehaviorSubject то что нужно, но не получилось с ним.

using System;
using System.Linq;
using System.Reactive.Linq;

class Event { public Event(string a, int b) { A = a; B = b; } public readonly string A; public readonly int B; public override string ToString() { return A + " " + B; } }

public class Program
{
    public static void Main()
    {
        var events = Observable.Range(1, 10).Select(i => new Event("Regular", i));

        var old = 0;
        var generatedEvents = events
            .Where(e => e.B % 2 == 0)
            .Select(e => {
                var ret = new Event("Generated, Old=" + old, e.B * 3);
                old = e.B; // Set old
                return ret;
            });

        var allEvents = events.Merge(generatedEvents);

        allEvents.Subscribe(Console.WriteLine);
    }
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: [Rx] Состояние
От: Sinix  
Дата: 04.11.15 11:50
Оценка: 18 (1)
Здравствуйте, _NN_, Вы писали:

_NN>Как правильно убрать переменную и сделать код чище ?

_NN>Мне кажется BehaviorSubject то что нужно, но не получилось с ним.
Observable.Scan():
http://www.zerobugbuild.com/?p=213
https://social.msdn.microsoft.com/Forums/en-US/852f79b9-3612-44ad-bcf1-b55b030e53ce/how-can-i-access-current-and-previous-value-in-stream
Re: [Rx] Состояние
От: TK Лес кывт.рф
Дата: 04.11.15 11:54
Оценка: 18 (1) +1
Здравствуйте, _NN_, Вы писали:

_NN>Как правильно убрать переменную и сделать код чище ?

_NN>Мне кажется BehaviorSubject то что нужно, но не получилось с ним.

В вашем случае можно использовать Scan:

var generatedEvents = events
.Where(e => e.B % 2 == 0)
.Scan(new { old = 0, e = default(Event) }, (ac, e) => {
var ret = new Event("Generated, Old=" + ac.old, e.B * 3);
return new { old = e.B, e = ret };
})
.Select(e => e.e);


или

var generatedEvents = Observable.Range(1, 10)
.Scan(new {old = 0, e = 0, hit = false}, (ac, e) => e % 2 == 0 ? new {old = e, e, hit = true} :new {ac.old, e, hit = false})
.SelectMany(ac => ac.hit ? new[] { new Event("Regular", ac.e), new Event("Generated, Old=" + ac.old, ac.e*3) } : new[] {new Event("Regular", ac.e)});

Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[2]: [Rx] Состояние
От: _NN_ www.nemerleweb.com
Дата: 04.11.15 15:29
Оценка:
Здравствуйте, TK, Вы писали:

Мне кажется было бы полезно иметь расширения в стиле Previous1 .. PreviousN .
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: [Rx] Состояние
От: Sinix  
Дата: 04.11.15 15:48
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Мне кажется было бы полезно иметь расширения в стиле Previous1 .. PreviousN .

http://www.introtorx.com/uat/content/v1.0.10621.0/14_TimeShiftedSequences.html#OverlappingBuffers

P.S. Для более-менее уверенной работы с rx весь intro to rx обязателен к изучению.
Re[3]: [Rx] Состояние
От: TK Лес кывт.рф
Дата: 04.11.15 18:56
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Мне кажется было бы полезно иметь расширения в стиле Previous1 .. PreviousN .


Skip(1) .. Skip(N)?
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[4]: [Rx] Состояние
От: _NN_ www.nemerleweb.com
Дата: 04.11.15 19:40
Оценка:
Здравствуйте, Sinix, Вы писали:
А почему тогда использовать Scan ,а не Buffer в этом случае ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: [Rx] Состояние
От: Sinix  
Дата: 04.11.15 20:45
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>А почему тогда использовать Scan ,а не Buffer в этом случае ?

И так и так можно. Scan для пары значенэий очевидней, Buffer понавороченней.
Re: [Rx] Состояние
От: _NN_ www.nemerleweb.com
Дата: 19.09.16 17:58
Оценка:
Вот есть два варианта решения, какой будет лучше и почему ?

1. Scan
public static IObservable<TResult> SelectWithPrevious<TSource, TResult>(
    this IObservable<TSource> source,
    Func<TSource, TSource, TResult> selector,
    TSource startingCurrent)
{
    if (source == null) throw new ArgumentNullException("source");
    if (selector == null) throw new ArgumentNullException("selector");

    return source
        .Scan(
            new { Current = startingCurrent, Previous = default(TSource) },
            (previous, current) => new { Current = current, Previous = previous.Current })
        .Select(
            previousAndCurrent =>
                    selector(previousAndCurrent.Current, previousAndCurrent.Previous));
}


2. Переменная
public static IObservable<TResult> SelectWithPrevious<TSource, TResult>(
    this IObservable<TSource> source,
    Func<TSource, TSource, TResult> selector,
    TSource startingCurrent)
{
    if (source == null) throw new ArgumentNullException("source");
    if (selector == null) throw new ArgumentNullException("selector");

    var current = startingCurrent;
    return source
        .Select(
            e =>
            {
                var previous = current;
                current = e;
                return selector(current, previous);
            });
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: [Rx] Состояние
От: Sinix  
Дата: 20.09.16 11:07
Оценка: 6 (1)
Здравствуйте, _NN_, Вы писали:

_NN>Вот есть два варианта решения, какой будет лучше и почему ?


Первый, т.к. он гарантированно останется работоспособным, если в Rx поменяется соглашение по OnNext.
previousAndCurrent структурой только сделать, чтоб аллокаций лишних не городить на каждое событие.
Re[2]: [Rx] Состояние
От: ionoy Эстония www.ammyui.com
Дата: 20.09.16 14:41
Оценка:
Здравствуйте, _NN_, Вы писали:

_NN>Вот есть два варианта решения, какой будет лучше и почему ?


А чем Buffer не угодил?

Observable.Range(0,100)
          .Buffer(2, 1)
          .Where(lst => lst.Count == 2)
          .Subscribe(lst => Debug.WriteLine(lst[0].ToString() + " " + lst[1].ToString()));
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
Re[3]: [Rx] Состояние
От: Sinix  
Дата: 20.09.16 14:42
Оценка:
Здравствуйте, ionoy, Вы писали:

I>А чем Buffer не угодил?

И так и так можно. Scan для пары значенэий очевидней, Buffer понавороченней.

^)
Re[4]: [Rx] Состояние
От: ionoy Эстония www.ammyui.com
Дата: 20.09.16 14:47
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, ionoy, Вы писали:


I>>А чем Buffer не угодил?

S>

S>И так и так можно. Scan для пары значенэий очевидней, Buffer понавороченней.

S>^)

Я бы сказал наоборот. Буфер предназначен именно для задач, когда нужно обрабатывать несколько последних значений. Скан — значительно более универсальный инструмент, а потому его использование не такое очевидное.
www.livexaml.com
www.ammyui.com
www.nemerleweb.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.