Краткий способ преобразования списка int в список перечислений

Мне нужно преобразовать список значений int в список значений enum и наоборот. Я могу создать простой метод преобразования, но хотел посмотреть, есть ли более краткий способ справиться с этим.

Вот как выглядят мои значения перечисления:

public enum AutoShipOption
{
   Monthly = 2,
   Weekly = 1,
   Yearly = 3,
   Undefined = 0
}

И в моем классе, который я использую для определения элемента магазина, я получаю List<int>, который мне нужно преобразовать в List<AutoShipOption>. Как я уже сказал, легко создать простой метод, который будет обрабатывать эту проблему и который будет выглядеть следующим образом:

public List<AutoShipOption> AutoShipOptionsMapper(List<int> values)
{
   var options = new List<AutoShipOption>();

   if (values == null || values.Count == 0)
      return options;

   foreach(var item in values)
      if (item > 0)
         options.Add((AutoShipOption)item);

   return options;
}

Есть ли более краткий способ справиться с этим преобразованием?

Возможно ли, чтобы List<int> содержал недопустимые значения перечисления?

Steve 04.08.2024 19:14
I need to convert a list of int values to list of enum values and vice versa, я вижу только попытку преобразовать список int в список перечислений, вам тоже нужен список перечислений в список int?
Trevor 04.08.2024 19:27

@Стив. Кратко? Какова семантика AutoShipOptionsMapper? if (item > 0) Я часто критикую собеседования по шаблонному кодированию, потому что, если ваши данные содержат значения, которые не имеют смысла — что это значит? Вероятно, вам нужна ошибка, а не игнорирование мусора. (Это не сопоставление, а фильтрация — остерегайтесь своего имени). Кроме того, иногда вы получаете один и тот же (пустой) список, а иногда — новый список. Безопасно ли добавлять в список (нет), так почему бы не вернуть массив? Имейте в виду, что с точки зрения языка допустимо, чтобы перечисление AutoShipOption содержало любое целое значение.

Wyck 04.08.2024 19:32
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
96
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете использовать LINQ Cast, как показано ниже:

var ints = new List<int> { 0, 1, 2, 3 };
var enums = ints
    .Where(x => Enum.IsDefined<AutoShipOption>(x))
    .Cast<AutoShipOption>()
    .ToList();

Такой метод можно инкапсулировать в некоторые общие методы расширения для IEnumerable и List:

public static class EnumEnumerableExtensions
{
    public static List<T> SafeListCast<T>(this List<T> list)
        where T : struct, Enum
    {
        return list.SafeCast().ToList();
    }

    public static IEnumerable<T> SafeCast<T>(this IEnumerable<T> enumerable)
        where T : struct, Enum
    {
        return enumerable
            .Where(Enum.IsDefined)
            .Cast<T>();
    }
}

Тогда пример будет упрощен:

var ints = new List<int> { 0, 1, 2, 3 };
var enums = ints.SafeListCast<AutoShipOption>();

Это преобразуется в IEnumerable<AutoShipOption>, а не в List<AutoShipOption>. Вам нужно будет написать ints.Cast<AutoShipOption>().ToList()

Wyck 04.08.2024 19:13

Что произойдет, если в этом решении для перечисления не существует значения? См. ответ SELA ниже, чтобы узнать что-то менее подверженное ошибкам.

Trevor 04.08.2024 19:35

@Trevor Я следовал «подверженному ошибкам» подходу, применил ОП, и это предположило, что это безопасно. Я сосредоточился на простоте, которая была главной целью. Тем не менее, это исправил.

Michał Turczyn 04.08.2024 19:59
Ответ принят как подходящий

Это все, что нужно через LINQ:

      public static List<AutoShipOption> AutoShipOptionsMapper(List<int> values)
        {
            if (values == null)
                return new List<AutoShipOption>();

            return values
                .Where(item => Enum.IsDefined(typeof(AutoShipOption), item))
                .Select(item => (AutoShipOption)item)
                .ToList();
        }

См. полный код ниже:

using System;
using System.Collections.Generic;
using System.Linq;

namespace EnumConversion
{
    public enum AutoShipOption
    {
        Monthly = 2,
        Weekly = 1,
        Yearly = 3,
        Undefined = 0
    }

    class Program
    {
        static void Main(string[] args)
        {
            List<int> intValues = new List<int> { 1, 2, 3, 4, 0, -1 };
            List<AutoShipOption> enumValues = AutoShipOptionsMapper(intValues);
            Console.WriteLine("AutoShipOptions values:");
            foreach (var option in enumValues)
            {
                Console.WriteLine(option);
            }
        }

        public static List<AutoShipOption> AutoShipOptionsMapper(List<int> values)
        {
            if (values == null)
                return new List<AutoShipOption>();

            return values
                .Where(item => Enum.IsDefined(typeof(AutoShipOption), item))
                .Select(item => (AutoShipOption)item)
                .ToList();
        }
    }
}

См. рабочий .netfiddle здесь

Другие вопросы по теме

Blazor EditForm: кнопка отключения приводит к тому, что все нетронутые поля помечаются как недействительные
Почему я не могу использовать DLL .NET 8 из моего приложения .NET Framework 4.7.2 Windows Forms?
.NET 8: MemoryCache SlidingExpiration без доступа
Не удалось загрузить файл или сборку «System.Diagnostics.DiagnosticSource», версия = 6.0.0.0. Система не может найти указанный файл
Зачем использовать структуру для хранения констант, а не статический класс?
Невозможно получить доступ к наблюдаемому свойству в модели представления из соответствующего файла .xaml представления — .NET MAUI MVVM
Устойчивые функции Azure не вызываются при использовании с триггером Q с использованием управляемого удостоверения
Как я могу преобразовать этот SQL-запрос в linq, когда у меня есть подзапрос, группировка и предложение?
Проблема развертывания Blazor WASM Core в Azure
Преобразование оператора foreach в оператор выбора