Member 14800672 Ответов: 3

Как получить неиспользуемые данные в C#


У меня есть список дней
List<string> days = new List<string>();


сейчас там только Солнце, понедельник и среда.

У меня также есть перечисление

enum WeekDays
{
    Sunday,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
}


я хочу получить неиспользованные дни
так что результат должен быть вторник,четверг,пятница и сб.

Что я уже пробовал:

я пытался сделать несколько вещей, но безрезультатно не могу вам помочь. Я новичок в Си#

Nelek

как цикл, проходящий через все возможности перечисления и просящий список найти каждую из них, чтобы увидеть, используются ли они?

3 Ответов

Рейтинг:
2

Daniele Rota Nodari

Тогда у вас есть список имена из дней, заполненных только 3 именами и нужных всем остальным дням

Прежде всего, вы пытаетесь сравнить строка значения для будни значения, где строки должны быть именами будни ценности.

List<string> days = new List<string>();
days.Add(WeekDays.Sunday.ToString());
days.Add(WeekDays.Monday.ToString());
days.Add(WeekDays.Wednesday.ToString());

Вы не можете сравнить их без преобразования. Преобразование может быть в любом направлении, в зависимости от шансов повторного использования.
- Вы можете собрать имена всех будни значения, используя Перечисление.Метод getnames, в случае хранения во временной переменной или в статическом поле, чтобы избежать повторения операции.
- Вы можете конвертировать имена дни список к будни значения, используя Перечисление.Разобрать или Перечисление.метод tryparse, и хранить во временной переменной; в этом случае помните, что Перечисление.Разобрать будет бросать на непризнанные/плохие имена.
В обоих случаях вы можете использовать Система.Linq.Перечислимый.Кроме метод расширения.

Получите все отсутствующие имена в виде массива, а затем преобразуйте их в значения:
var missingNames = Enum.GetNames(typeof(WeekDays)).Except(days).ToArray();
var missingValues = Array.ConvertAll(missingNames, value => (WeekDays)Enum.Parse(typeof(WeekDays), value, true));


Преобразует используемые имена в значения в виде перечислимой последовательности, а затем получает все отсутствующие значения в виде массива:
var daysValues = days.Select(value => (WeekDays)Enum.Parse(typeof(WeekDays), value, true));
var missingValues = ((WeekDays[])Enum.GetValues(typeof(WeekDays))).Except(daysValues).ToArray();


Это самые компактные решения, но я бы разбил их на этапы составления, как для удобства чтения, так и для удобства обслуживания.
Я предлагаю вам ознакомиться с содержанием онлайн-справки и локальной документацией для всех методов (Enum.Parse, Enum.TryParse, Enum.Метод Getnames, Перечисление.GetValues, Массив.ConvertAll, Перечисли.Выберите, Перечислимый.Разве Что, Перечислимо.Метод toArray).
Имейте в виду, что эти решения дают массив результатов, которые лучше всего подходят в том случае, если вы будете выполнять над ними несколько операций и отлаживать их; если вы будете итерировать только один раз, то по крайней мере последний ToArray призыв не требуется.

Для Кроме метод работы, который вы должны добавить использование System.Linq; поверх исходного файла.


BillWoodruff

+5 очень тщательно !

0x01AA

Я думаю, что вы забыли нажать на звезды :-) ... или в системе голосования есть ошибка.

BillWoodruff

Привет, спасибо ! Я думал, что проголосовал.

Рейтинг:
1

BillWoodruff

Если вы много работаете с перечислениями, вы можете использовать методы расширения, чтобы скрыть сложность, а также разрабатывать и тестировать отдельно от основного кода приложения.

Два метода, показанные здесь, расширяют либо строку, либо тип; вот как они называются:

Будни понедельник = "Понедельник".ToEnum<будни>();

Будни пятница = typeof(будни).ToEnum<будни>("пятница");

Как только у вас есть эти "атомарные методы", тривиально добавлять другие расширения, которые выполняют операции над коллекциями с помощью Linq.

имхо, вы действительно платите цену за любой из них: первый пример расширяет строку; я думаю, что расширение основной типы - это вообще ошибка. Во втором примере вы платите цену за довольно неудобную структуру формата вызова.

public static class EnumExtensions
{
    // string => Enum value
    public static TEnum ToEnum<TEnum>(this string str)
    where TEnum : struct, IConvertible
    {
        Type tenum = typeof(TEnum);

        if (! tenum.IsEnum)
            throw new ArgumentException("TEnum must be an Enum type");

        if (!Enum.IsDefined(tenum, str))
        {
            throw new ArgumentException($"{str} is not a valid string for conversion to {tenum.FullName}");
        }

        return (TEnum)Enum.Parse(tenum, str);
    }

    // Enum Type, string, optional bool => Enum value
    public static TEnum ToEnum<TEnum>(this Type tenum, string str, bool ignorecase = false)
        where TEnum : struct, IConvertible
    {
        if (! tenum.IsEnum)
            throw new ArgumentException("TEnum must be an Enum type");

        TEnum result;

        // note ignore case parameter
        if (Enum.TryParse<TEnum>(str, ignorecase, out result))
        {
            return result;
        }

        throw new ArgumentException($"{str} is not a valid string for conversion to {tenum.FullName}");
    }
}


Рейтинг:
0

OriginalGriff

Попробуй:

private enum WeekDays
    {
    Sunday,
    Monday,
    Tuesday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    }
public List<string> days = new List<string>();
private void DoSomat()
    {
    days.Add("Sunday");
    days.Add("Monday");
    days.Add("Wednesday");
    string[] allDays = Enum.GetNames(typeof(WeekDays));
    var missing = allDays.Except(days);
    ...
    }


Member 14800672

Большое спасибо.
Если у меня есть переменная (var), которая имеет 2 объекта
где день равен сцепленному значению
[0] Воскресенье,Понедельник
[1] Среда,Четверг

Я хочу применить ваше решение на нем
string[] allDays = перечисление.GetNames(typeof(будни));
отсутствует оператор var = сайт Alldays.Кроме(дней);

поэтому я хочу поместить allDays.Except() все дни в переменную, о которой я упоминал выше, как это сделать?

OriginalGriff

Не.
Вы смешиваете коллекции, поэтому сначала сопоставьте их в более "нормальной" форме - вы можете использовать строку.Разделить, чтобы разбить их, а затем объединить в один массив, список или другую коллекцию.
Судя по всему, вы приняли здесь пару плохих решений - вместо этого вам следует думать об использовании перечисления как есть, а не полагаться на строки.
Например, если вы зададите значения перечисления в виде битов, вы можете объединить их в одно значение перечисления:

        private enum WeekDays
            {
            Sunday = 1,
            Monday = 2,
            Tuesday = 4,
            Wednesday = 8,
            Thursday = 16,
            Friday = 32,
            Saturday = 64,
            }

            WeekDays firstTwo = WeekDays.Sunday | WeekDays.Monday;
Что намного эффективнее - и надежнее - чем струны.

Откуда берутся данные, разделенные запятыми?

Member 14800672

Не могли бы вы объяснить подробнее, что я не получил биты и перечисления, не могли бы вы показать мне, как это сделать?

запятая отделенная происходит от этого
ВАР groupLast = groupFirst
.GroupBy(x => new { x.Day })
.Выберите(г =&ГТ; новый
{
День = g.Key.Day,
groupedBy = g
});
Эта группа возвращает два объекта:
Дней = Вс,Пн
День = ср,чт

я хочу вернуться во вторник,пятницу и субботу

OriginalGriff

Это ничего не делает через запятую: он возвращает коллекцию анонимных объектов класса с двумя свойствами: The Day (который, как мы надеемся, является значением перечисления) и groupedby, которая содержит группу, содержащую коллекцию любых объектов, которые были в groupFirst Q, когда вы начали.

Запятые тут ни при чем - за исключением тех случаев, когда вы делаете с ними что-то еще ...
Загляните в отладчик - вы поймете, что я имею в виду.

Member 14800672

GroupFirst выполняет разделение запятой в днях и группирует их по другому полю
Так что это было сначала похоже
воскресенье-понедельник
воскресенье-понедельник
Среда, четверг
А группласт теперь группируется по дням, чтобы не получать повторяющихся значений, так что
воскресенье-понедельник
СР, Четверг
Итак, день здесь-это поле, которое исходит из БД, вот почему я сделал перечисление для сравнения с ним, так что вы сможете помочь сейчас?

BillWoodruff

+5