Git Product home page Git Product logo

linqtee's Introduction

Table of content

Table of contents generated with markdown-toc

LinqTee

LINQ-to-Object library to easily bifurcate LINQ data flows and join them back together.

You can split your collections data processing flow with Tee (T) and Wye (Y) easily.

It is inspired by the tee linux command (but not the same thing!).

What is LinqTee?

If you ever needed to build a fluent LINQ-to-object chain, but needed to process parts of data differently, this library call help you having a cleaner code.

Install

PM > Install-Package LinqTee -Version 0.1.0-beta

Examples

left-right concatenation

    bool LargerThan5(int x) => x > 5;

    IEnumerable<int> values = Enumerable.Range(1, 10);
    var processedValues = values
            //Split enumerable with some criteria
            .Tee(LargerThan5)
            //We choose to process both streams
            .Process()
            //Do something with the left side
            .Left(even => even * 2)
            //Do something else with the right side
            .Right(odd => odd * 7)
            //'wye' (join) them together.
            .Wye() //<-- operate left-to-right
            //In this case we concat the left with right side.
            .Concatenate();

right-left concatenation

    bool LargerThan5(int x) => x > 5;

    IEnumerable<int> values = Enumerable.Range(1, 10);
    var processedValues = values
            .Tee(LargerThan5)
            .Process()
            .Left(even => even * 2)
            .Right(odd => odd * 7)
            //Operate first on the right collection
            .WyeRight() //<-- right-to-left
            .Concatenate();

zipping collections

It works in a similar way of lodash.

It weaves/intersperses two collections into one.

Pseudo-code

var odds = new []{1,3,5,7,9};
var evens = new []{2,4,6,8,10};

var values = zip(odds, evens);

//Values would be equal to
{1,2,3,4,5,6,7,8,9,10}

//We could also right zip them
var values2 = zipRight(odds, evens);

//It would be equal to
{2,1,4,3,6,5,8,7,10,9}

Real code (left-to-right):

    bool LargerThan5(int x) => x > 5;

    IEnumerable<int> values = Enumerable.Range(1, 10);
    var processedValues = values
            .Tee(LargerThan5)
            .Process()
            .Left(even => even * 2)
            .Right(odd => odd * 7)
            //Operate first on the right collection
            .Wye() //<-- left-to-right
            .Zip();

Real code (right-to-left)

    bool LargerThan5(int x) => x > 5;

    IEnumerable<int> values = Enumerable.Range(1, 10);
    var processedValues = values
            .Tee(LargerThan5)
            .Process()
            .Left(even => even * 2)
            .Right(odd => odd * 7)
            //Operate first on the right collection
            .WyeRight() //<-- right-to-left
            .Zip();

Public Interface

The API has been built to avoid misusing it.
Intellisense will be your best friend, but just in case:

IEnumerable<T>
    .Tee(T => bool)
    [   
        .Collect()
        { .Left(ref IList<T>) | .IgnoreLeft() }
        { .Right(ref IList<T>) | IgnoreRight() }
    ]
    [
        .Process()
        { .Left(T -> bool) | IgnoreLeft() }
        { .Right(T -> bool | IgnoreRight() }
        { .Wye() | .WyeRight() }
        { .Concatenate() | .Zip() | .OperateWith((IEnumerable<T>, IEnumerable<T>) => IEnumerable<T>) }
    ]
    [
        { .Wye() | .WyeRight() }
        { .Concatenate() | .Zip() | .OperateWith((IEnumerable<T>, IEnumerable<T>) => IEnumerable<T>) }
    ]
    ;

Custom Wye operations

By default the library includes concatenation and zip to merge a Tee operation.

You can create any custom logic by implementing the IWyeableOperation<T> interface.

You only have to implement how you want to merge two collections. The interface has only a single method with two parameters which by convenience have been called left and right.

    public interface IWyeableOperation<T>
    {
        IEnumerable<T> Operate(IEnumerable<T> left, IEnumerable<T> right);
    }

You don't have to implement the opposite mapping. When using WyeRight() method, your operation will just receive the left and right original collections swapped.

Concatenate real example

Implementation

    public class ConcatenateMyWay<T> : IWyeableOperation<T>
    {
        public IEnumerable<T> Operate(IEnumerable<T> left, IEnumerable<T> right)
        {
            return left.Concat(right);
        }
    }

Then you can use it as

    bool LargerThan5(int x) => x > 5;

    IEnumerable<int> values = Enumerable.Range(1, 10);
    var processedValues = values
            .Tee(LargerThan5)
            .Process()
            .Left(even => even * 2)
            .Right(odd => odd * 7)
            .Wye()
            .OperateWith(new ConcatenateMyWay()); //<-- generic way

We recommend creating your own extension method to have a cleaner code.

        public static IEnumerable<T> ConcatenateMyWay<T>(this IWyeable<T> wyeable)
        {
            return wyeable.OperateWith(new Concatenate<T>());
        }

Then you can invoke it as

    bool LargerThan5(int x) => x > 5;

    IEnumerable<int> values = Enumerable.Range(1, 10);
    var processedValues = values
            .Tee(LargerThan5)
            .Process()
            .Left(even => even * 2)
            .Right(odd => odd * 7)
            .Wye()
            .ConcatenateMyWay(); // <-- much cleaner

Nesting calls

Nothing prevents you from creating more complex nesting uses.

    bool LargerThan5(int x) => x > 5;

    var actual = Enumerable.Range(1, 10)
            .Tee(x => x % 2 == 0)
            .Process()
            .Left(even =>
            {
                return even
                    .Tee(LargerThan5)
                    .Process()
                    .Left(evenLarger5 => evenLarger5)
                    .Right(evenSmaller5 => evenSmaller5)
                    .Wye()
                    .Concatenate();
            })
            .Right(odd =>
            {
                return odd
                    .Tee(LargerThan50)
                    .Process()
                    .Left(oddLarger5 => oddLarger5)
                    .Right(oddSmaller5 => oddSmaller5)
                    .Wye()
                    .Concatenate();
            })
            .Wye()
            .Concatenate();

Starting range collection:

[1,2,3,4,5,6,7,8,9,10]

actual variable result:

[6,8,10,2,4,7,9,1,3,5]

linqtee's People

Contributors

rulrok avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.