F # Array.choose идентификатор эквивалентен в C # - PullRequest
1 голос
/ 29 апреля 2019

Мне нравится использовать Array.choose id в F # на Option [].Каков наилучший способ сделать это в C # для Nullable []?

--- Отредактировано для получения превосходных комментариев ---
В F # я использую Array.choose id, чтобы отфильтровать None: Option<'T>[] -> 'T [].
Какой хороший способ отфильтровать null в C # с помощью Linq: Nullable<T>[] => T []?

Ответы [ 3 ]

3 голосов
/ 29 апреля 2019

Я бы перевел это в C #

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

Вы можете опустить ToArray(), если вы просто хотите, как IEnumerable, и .Select(..), если вы не хотите, чтобы nullables распаковывались

1 голос
/ 30 апреля 2019

Вы можете использовать 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();
0 голосов
/ 30 апреля 2019

Если вы поклонник F # Option, вам может понравиться Необязательная библиотека в C #.

В любом случае, мне нравится использовать для этого метод расширения.Я использую его с этой дополнительной библиотекой, но вот версия 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();
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...