繁体   English   中英

F#Array.choose id等效于C#

[英]F# Array.choose id equivalent in C#

我喜欢在Option []的F#中使用Array.choose ID。 在C#中为Nullable []执行此操作的最佳方法是什么?

---编辑以发表出色的评论---
在F#中,我使用Array.choose id过滤掉NoneOption<'T>[] -> 'T []
用Linq在C#中过滤出null的好方法是什么: Nullable<T>[] => T []

我会在C#中将其翻译成

int?[] all = new int?[3] { 10, null, 100 };
int[] chosen = all
    .Where(e => e.HasValue)
    .Select(e => e.Value)
    .ToArray();

如果只希望将其作为IEnumerable,则可以省略ToArray()如果不希望将nullable拆包,则可以省略.Select(..)

您可以使用SelectMany给定的另一个函数来转换T? IEnumerable<T>

public static IEnumerable<T> ToSeq<T>(this T? v) where T : struct
{
    if (v.HasValue)
    {
        yield return v.Value;
    }
}

然后:

var nullables = new int?[] { null, 1, 4, null, 3, null, 29 };
int[] values = nullables.SelectMany(ni => ni.ToSeq()).ToArray();

如果您是F#Option的粉丝,您可能会喜欢C#中的Optional库。

无论如何,我喜欢为此使用扩展方法。 我将其与该Optional库一起使用,但这是一个Nullable版本。 此版本仅限于输出值类型,但Option版本也可以处理引用类型。

/// <summary>
///     Allows you to map and filter in a single operation, by passing in a function that returns
///     a Nullable containing the output that should be included in the final result.
///     Only the values that are not null are included in the resulting sequence.
/// </summary>
public static IEnumerable<T2> Choose<T1, T2>(this IEnumerable<T1> enumerable, Func<T1, T2?> selector) where T2 : struct
{
    if (enumerable is null) throw new ArgumentNullException(nameof(enumerable));
    if (selector is null) throw new ArgumentNullException(nameof(selector));

    // The nested function ensures argument validation happens immediately, rather than
    // being delayed until the caller starts iterating the results.

    IEnumerable<T2> iterator()
    {
        foreach (var item in enumerable)
        {
            var output = selector(item);
            if (output.HasValue)
                yield return output.Value;
        }
    }

    return iterator();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM