更新IEnumerable的Tail扩展方法
This commit is contained in:
parent
537b7280de
commit
6be9bbcb8e
|
@ -11,21 +11,77 @@ public static class IEnumerableExtension
|
||||||
|
|
||||||
public static Func<T, IEnumerable<T>> Return<T>() => t => List(t);
|
public static Func<T, IEnumerable<T>> Return<T>() => t => List(t);
|
||||||
|
|
||||||
public static Option<T> Head<T>(this IEnumerable<T> list)
|
/// <summary>
|
||||||
|
/// 将序列内第一条元素转换为<see cref="Option"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source"></param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Option<T> Head<T>(this IEnumerable<T> source)
|
||||||
{
|
{
|
||||||
if (list is null)
|
if (source is null)
|
||||||
{
|
{
|
||||||
return Option.None;
|
return Option.None;
|
||||||
}
|
}
|
||||||
var enumerator = list.GetEnumerator();
|
var first = source.FirstOrDefault();
|
||||||
return enumerator.MoveNext() ? Option.Some(enumerator.Current) : Option.None;
|
return first is not null ? Option.Some(first) : Option.None;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static R Match<T, R>(this IEnumerable<T> list, Func<R> Empty, Func<T, IEnumerable<T>, R> Otherwise)
|
/// <summary>
|
||||||
=> list.Head().Match(Empty, (head) => Otherwise(head, list.Skip(1)));
|
/// 给定谓词,查询序列内第一条数据并将其转换为<see cref="Option"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source">数据源</param>
|
||||||
|
/// <param name="predicate">谓词</param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Option<T> Head<T>(this IEnumerable<T> source, Func<T, bool> predicate)
|
||||||
|
{
|
||||||
|
if (source is null)
|
||||||
|
{
|
||||||
|
return Option.None;
|
||||||
|
}
|
||||||
|
var first = source.Where(predicate).FirstOrDefault();
|
||||||
|
return first is not null ? Option.Some(first) : Option.None;
|
||||||
|
}
|
||||||
|
|
||||||
public static IEnumerable<R> Map<T, R>(this IEnumerable<T> list, Func<T, R> func)
|
/// <summary>
|
||||||
=> list.Select(func);
|
/// 将序列内最后一个元素转换为<see cref="Option"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source"></param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Option<T> Tail<T>(this IEnumerable<T> source)
|
||||||
|
{
|
||||||
|
if (source is null)
|
||||||
|
{
|
||||||
|
return Option.None;
|
||||||
|
}
|
||||||
|
var tail = source.LastOrDefault();
|
||||||
|
return tail is not null ? Option.Some(tail) : Option.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 给定谓词,查询序列内最后一条数据并将其转换为<see cref="Option"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source">数据源</param>
|
||||||
|
/// <param name="predicate">谓词</param>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Option<T> Tail<T>(this IEnumerable<T> source, Func<T, bool> predicate)
|
||||||
|
{
|
||||||
|
if (source is null)
|
||||||
|
{
|
||||||
|
return Option.None;
|
||||||
|
}
|
||||||
|
var last = source.Where(predicate).LastOrDefault();
|
||||||
|
return last is not null ? Option.Some(last) : Option.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static R Match<T, R>(this IEnumerable<T> source, Func<R> Empty, Func<T, IEnumerable<T>, R> Otherwise)
|
||||||
|
=> source.Head().Match(Empty, (head) => Otherwise(head, source.Skip(1)));
|
||||||
|
|
||||||
|
public static IEnumerable<R> Map<T, R>(this IEnumerable<T> source, Func<T, R> func)
|
||||||
|
=> source.Select(func);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 给集合内每个元素执行一个无返回值函数
|
/// 给集合内每个元素执行一个无返回值函数
|
||||||
|
@ -37,11 +93,11 @@ public static class IEnumerableExtension
|
||||||
public static IEnumerable<Unit> ForEach<T>(this IEnumerable<T> source, Action<T> action)
|
public static IEnumerable<Unit> ForEach<T>(this IEnumerable<T> source, Action<T> action)
|
||||||
=> source.Map(action.ToFunc()).ToImmutableList();
|
=> source.Map(action.ToFunc()).ToImmutableList();
|
||||||
|
|
||||||
public static IEnumerable<R> Bind<T, R>(this IEnumerable<T> list, Func<T, IEnumerable<R>> func)
|
public static IEnumerable<R> Bind<T, R>(this IEnumerable<T> source, Func<T, IEnumerable<R>> func)
|
||||||
=> list.SelectMany(func);
|
=> source.SelectMany(func);
|
||||||
|
|
||||||
public static IEnumerable<R> Bind<T, R>(this IEnumerable<T> list, Func<T, Option<R>> func)
|
public static IEnumerable<R> Bind<T, R>(this IEnumerable<T> source, Func<T, Option<R>> func)
|
||||||
=> list.Bind(t => func(t).AsEnumerable());
|
=> source.Bind(t => func(t).AsEnumerable());
|
||||||
|
|
||||||
|
|
||||||
private static IEnumerable<T> List<T>(T t)
|
private static IEnumerable<T> List<T>(T t)
|
||||||
|
|
|
@ -107,6 +107,10 @@ public static class OptionExtension
|
||||||
public static Either<L, R> ToEither<L, R>(this Option<L> option, R error)
|
public static Either<L, R> ToEither<L, R>(this Option<L> option, R error)
|
||||||
=> option.IsSome() ? Either.Right(error) : Either.Left(option.Value);
|
=> option.IsSome() ? Either.Right(error) : Either.Left(option.Value);
|
||||||
|
|
||||||
|
public static Either<L, string> ToEither<L, R>(this Option<L> option, string error)
|
||||||
|
=> option.IsSome() ? Either.Right(error) : Either.Left(option.Value);
|
||||||
|
|
||||||
|
|
||||||
#region Linq式
|
#region Linq式
|
||||||
|
|
||||||
public static Option<R> Select<T, R>(this Option<T> source, Func<T, R> mapping)
|
public static Option<R> Select<T, R>(this Option<T> source, Func<T, R> mapping)
|
||||||
|
|
|
@ -49,7 +49,6 @@ public readonly struct Either<TLeft, TRight>
|
||||||
=> Match(l => $"Left({l})", r => $"Right({r})");
|
=> Match(l => $"Left({l})", r => $"Right({r})");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public readonly struct Left<TLeft>
|
public readonly struct Left<TLeft>
|
||||||
{
|
{
|
||||||
internal TLeft Value { get; }
|
internal TLeft Value { get; }
|
||||||
|
|
Loading…
Reference in New Issue