Skip to content
This repository was archived by the owner on Sep 21, 2021. It is now read-only.

Solves unnecessarily iterating list twice #5

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 45 additions & 26 deletions src/Nano.DependencyInjector/ListExtension.cs
Original file line number Diff line number Diff line change
@@ -1,67 +1,86 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace Nano.DependencyInjector
{
public static class ListExtensions
{
public static ITrue<T> If<T>(this IEnumerable<T> list, Predicate<T> ifStatement)
{
var trueResult = list.Where(i => ifStatement(i));
var falseResult = list.Where(i => !ifStatement(i));

return new IfResult<T>(trueResult, falseResult);
return new IfTrueWrapper<T>(list, ifStatement);
}
}

public class IfResult<T> : ITrue<T>
public class IfTrueWrapper<T> : ITrue<T>
{
private readonly IEnumerable<T> trueResult;
private readonly IEnumerable<T> falseResult;
public IEnumerable<T> List { get; }
public Predicate<T> IfStatement { get; }
public Action<T> TrueAction { get; private set; }

public IfResult(IEnumerable<T> trueResult, IEnumerable<T> falseResult)
public IfTrueWrapper(IEnumerable<T> list, Predicate<T> ifStatement)
{
this.trueResult = trueResult;
this.falseResult = falseResult;
List = list;
IfStatement = ifStatement;
}

public IFalse<T> True(Action<T> act)
public IFalse<T> True(Action<T> trueAction)
{
foreach (var item in trueResult)
{
act(item);
}
TrueAction = trueAction;

return new ElseResult<T>(falseResult);
return new ElseResult<T>(this);
}
}

public class ElseResult<T> : IFalse<T>
{
private readonly IEnumerable<T> falseResult;
private readonly IfTrueWrapper<T> _ifTrueWrapper;

public ElseResult(IfTrueWrapper<T> ifTrueWrapper)
{
_ifTrueWrapper = ifTrueWrapper;
}

public ElseResult(IEnumerable<T> falseResult)
void IFalse<T>.False(Action<T> falseAction)
{
this.falseResult = falseResult;
InternalRun(_ifTrueWrapper.List, _ifTrueWrapper.IfStatement, _ifTrueWrapper.TrueAction, falseAction);
}

void IFalse<T>.False(Action<T> act)
public void Run()
{
foreach (var item in falseResult)
InternalRun(_ifTrueWrapper.List, _ifTrueWrapper.IfStatement, _ifTrueWrapper.TrueAction, null);
}

private void InternalRun(IEnumerable<T> list,
Predicate<T> ifStatement,
Action<T> trueAction,
Action<T> falseAction)
{
foreach (var item in list)
{
act(item);
if (ifStatement(item))
{
trueAction(item);
}
else
{
falseAction?.Invoke(item);
}
}
}
}

public interface IRunnable
{
void Run();
}

public interface ITrue<T>
{
IFalse<T> True(Action<T> act);
IFalse<T> True(Action<T> trueAction);
}

public interface IFalse<T>
public interface IFalse<T> : IRunnable
{
void False(Action<T> act);
void False(Action<T> falseAction);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ private static object CreateInstance(IServiceProvider provider, Type type)
object instance;
ConstructorInfo publicConstructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public,
null, new[] {typeof(string)}, null);

if (publicConstructor == null)
{
instance = System.Runtime.Serialization.FormatterServices
Expand Down
23 changes: 21 additions & 2 deletions tests/Nano.DependencyInjector.Tests/ListExtensionTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using Xunit;

Expand All @@ -10,14 +11,32 @@ public void TrueFunc_Should_Get_Items_When_Statement_Is_True()
{
var falseHeroes = new List<string>();
var heroes = new List<string>() {"Conan", "Spawn", "Batman"};
heroes.If(IsBestHero)
heroes.If(IsThisTheBestHero)
.True(t => Assert.Equal("Conan", t))
.False(f => falseHeroes.Add(f));

Assert.Equal(2, falseHeroes.Count);
}

private bool IsBestHero(string hero)
[Fact]
public void There_Can_Be_Only_True_Action()
{
bool called = false;

void TrueAct(string t)
{
called = true;
}

var heroes = new List<string>() {"Conan", "Spawn", "Batman"};
heroes.If(IsThisTheBestHero)
.True(TrueAct)
.Run();

Assert.True(called);
}

private bool IsThisTheBestHero(string hero)
{
return hero == "Conan";
}
Expand Down