From 6be9bbcb8ed7d7e6a7868b67856a0823731e7e85 Mon Sep 17 00:00:00 2001 From: Sanchime Date: Thu, 12 May 2022 21:58:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0IEnumerable=E7=9A=84Tail?= =?UTF-8?q?=E6=89=A9=E5=B1=95=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Core/Extensions/IEnumerable.cs | 80 ++++++++++++++++--- Sanchime.Functional/Core/Extensions/Option.cs | 4 + Sanchime.Functional/Core/Products/Either.cs | 1 - 3 files changed, 72 insertions(+), 13 deletions(-) diff --git a/Sanchime.Functional/Core/Extensions/IEnumerable.cs b/Sanchime.Functional/Core/Extensions/IEnumerable.cs index 1bf9a10..851a94c 100644 --- a/Sanchime.Functional/Core/Extensions/IEnumerable.cs +++ b/Sanchime.Functional/Core/Extensions/IEnumerable.cs @@ -11,21 +11,77 @@ public static class IEnumerableExtension public static Func> Return() => t => List(t); - public static Option Head(this IEnumerable list) + /// + /// 将序列内第一条元素转换为 + /// + /// + /// + /// + public static Option Head(this IEnumerable 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(this IEnumerable list, Func Empty, Func, R> Otherwise) - => list.Head().Match(Empty, (head) => Otherwise(head, list.Skip(1))); + /// + /// 给定谓词,查询序列内第一条数据并将其转换为 + /// + /// 数据源 + /// 谓词 + /// + /// + public static Option Head(this IEnumerable source, Func 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 Map(this IEnumerable list, Func func) - => list.Select(func); + /// + /// 将序列内最后一个元素转换为 + /// + /// + /// + /// + public static Option Tail(this IEnumerable source) + { + if (source is null) + { + return Option.None; + } + var tail = source.LastOrDefault(); + return tail is not null ? Option.Some(tail) : Option.None; + } + + /// + /// 给定谓词,查询序列内最后一条数据并将其转换为 + /// + /// 数据源 + /// 谓词 + /// + /// + public static Option Tail(this IEnumerable source, Func 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(this IEnumerable source, Func Empty, Func, R> Otherwise) + => source.Head().Match(Empty, (head) => Otherwise(head, source.Skip(1))); + + public static IEnumerable Map(this IEnumerable source, Func func) + => source.Select(func); /// /// 给集合内每个元素执行一个无返回值函数 @@ -37,11 +93,11 @@ public static class IEnumerableExtension public static IEnumerable ForEach(this IEnumerable source, Action action) => source.Map(action.ToFunc()).ToImmutableList(); - public static IEnumerable Bind(this IEnumerable list, Func> func) - => list.SelectMany(func); + public static IEnumerable Bind(this IEnumerable source, Func> func) + => source.SelectMany(func); - public static IEnumerable Bind(this IEnumerable list, Func> func) - => list.Bind(t => func(t).AsEnumerable()); + public static IEnumerable Bind(this IEnumerable source, Func> func) + => source.Bind(t => func(t).AsEnumerable()); private static IEnumerable List(T t) diff --git a/Sanchime.Functional/Core/Extensions/Option.cs b/Sanchime.Functional/Core/Extensions/Option.cs index 6805789..7e6d285 100644 --- a/Sanchime.Functional/Core/Extensions/Option.cs +++ b/Sanchime.Functional/Core/Extensions/Option.cs @@ -107,6 +107,10 @@ public static class OptionExtension public static Either ToEither(this Option option, R error) => option.IsSome() ? Either.Right(error) : Either.Left(option.Value); + public static Either ToEither(this Option option, string error) + => option.IsSome() ? Either.Right(error) : Either.Left(option.Value); + + #region Linq式 public static Option Select(this Option source, Func mapping) diff --git a/Sanchime.Functional/Core/Products/Either.cs b/Sanchime.Functional/Core/Products/Either.cs index 669ea9c..01def07 100644 --- a/Sanchime.Functional/Core/Products/Either.cs +++ b/Sanchime.Functional/Core/Products/Either.cs @@ -49,7 +49,6 @@ public readonly struct Either => Match(l => $"Left({l})", r => $"Right({r})"); } - public readonly struct Left { internal TLeft Value { get; }