<commit_before>﻿using ReactiveMarrow;
using System;
using System.Reactive.Disposables;
using System.Reactive.Linq;

namespace Espera.Core
{
    internal static class ReactiveHelpers
    {
        /// <summary>
        /// Takes the left observable and combines it with the latest value of the right observable.
        /// This method is like <see cref="Observable.CombineLatest{TSource1,TSource2,TResult}"/>, 
        /// except it propagates only when the value of the left observable sequence changes.
        /// </summary>
        public static IObservable<TResult> Left<TLeft, TRight, TResult>(this IObservable<TLeft> left, IObservable<TRight> right, Func<TLeft, TRight, TResult> resultSelector)
        {
            TRight latest = default(TRight);
            bool initialized = false;

            var disp = new CompositeDisposable(2);

            right.Subscribe(x =>
            {
                latest = x;
                initialized = true;
            }).DisposeWith(disp);

            return Observable.Create<TResult>(o =>
            {
                left.Subscribe(x =>
                {
                    if (initialized)
                    {
                        o.OnNext(resultSelector(x, latest));
                    }
                }, o.OnError, o.OnCompleted).DisposeWith(disp);

                return disp;
            });
        }
    }
}<commit_msg>Save all the lines of code!<commit_after>﻿using ReactiveMarrow;
using System;
using System.Reactive.Disposables;
using System.Reactive.Linq;

namespace Espera.Core
{
    internal static class ReactiveHelpers
    {
        /// <summary>
        /// Takes the left observable and combines it with the latest value of the right observable.
        /// This method is like <see cref="Observable.CombineLatest{TSource1,TSource2,TResult}"/>, 
        /// except it propagates only when the value of the left observable sequence changes.
        /// </summary>
        public static IObservable<TResult> Left<TLeft, TRight, TResult>(this IObservable<TLeft> left, IObservable<TRight> right, Func<TLeft, TRight, TResult> resultSelector)
        {
            TRight latest = default(TRight);
            bool initialized = false;

            var disp = new CompositeDisposable(2);

            right.Subscribe(x =>
            {
                latest = x;
                initialized = true;
            }).DisposeWith(disp);

            return Observable.Create<TResult>(o =>
            {
                left.Where(_ => initialized)
                    .Subscribe(x => o.OnNext(resultSelector(x, latest)), 
                        o.OnError, o.OnCompleted)
                    .DisposeWith(disp);

                return disp;
            });
        }
    }
}
{'fraction_non_alphanumeric': 0.09632860777898945, 'fraction_numerical': 0.0021810250817884407, 'mean_word_length': 1.7741935483870968, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 28, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7232498', 'n_tokens_mistral': 744, 'n_tokens_neox': 707, 'n_words': 188}