更新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 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;
|
||||
}
|
||||
var enumerator = list.GetEnumerator();
|
||||
return enumerator.MoveNext() ? Option.Some(enumerator.Current) : Option.None;
|
||||
var first = source.FirstOrDefault();
|
||||
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)
|
||||
=> list.Head().Match(Empty, (head) => Otherwise(head, list.Skip(1)));
|
||||
/// <summary>
|
||||
/// 给定谓词,查询序列内第一条数据并将其转换为<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)
|
||||
=> list.Select(func);
|
||||
/// <summary>
|
||||
/// 将序列内最后一个元素转换为<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>
|
||||
/// 给集合内每个元素执行一个无返回值函数
|
||||
|
@ -37,11 +93,11 @@ public static class IEnumerableExtension
|
|||
public static IEnumerable<Unit> ForEach<T>(this IEnumerable<T> source, Action<T> action)
|
||||
=> source.Map(action.ToFunc()).ToImmutableList();
|
||||
|
||||
public static IEnumerable<R> Bind<T, R>(this IEnumerable<T> list, Func<T, IEnumerable<R>> func)
|
||||
=> list.SelectMany(func);
|
||||
public static IEnumerable<R> Bind<T, R>(this IEnumerable<T> source, Func<T, IEnumerable<R>> func)
|
||||
=> source.SelectMany(func);
|
||||
|
||||
public static IEnumerable<R> Bind<T, R>(this IEnumerable<T> list, Func<T, Option<R>> func)
|
||||
=> list.Bind(t => func(t).AsEnumerable());
|
||||
public static IEnumerable<R> Bind<T, R>(this IEnumerable<T> source, Func<T, Option<R>> func)
|
||||
=> source.Bind(t => func(t).AsEnumerable());
|
||||
|
||||
|
||||
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)
|
||||
=> 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式
|
||||
|
||||
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})");
|
||||
}
|
||||
|
||||
|
||||
public readonly struct Left<TLeft>
|
||||
{
|
||||
internal TLeft Value { get; }
|
||||
|
|
Loading…
Reference in New Issue