Найти пропущенные обязательные значения в списке - PullRequest
0 голосов
/ 16 июня 2019

Предположим, нам даны два списка (может быть любого типа примитива):

var arguments = new List<String>() {"a", "b", "c", "d", "e", "f", "g", "h"};
var required = new List<String>() {"c", "g"};

Все значения требуемого списка должны быть в списке аргументов.Если ничего не пропущено, вернуть null, иначе вернуть список отсутствующих аргументов.О, и требуемые значения не могут встречаться несколько раз, если это так, следует выдать исключение.

Это то, что мне удалось собрать:

private static IList<string> FindMissingRequiredValues(List<string> required, List<string> arguments)
        {
            var missing = new List<string>();
            foreach (var r in required)
            {
                if (!arguments.Contains(r))
                    missing.Add(r);
            }

            if (missing.Count == 0)
                missing = null;
            return missing;
        }

Это работает, но это нене заботиться о дубликатах, и это выглядит некрасиво.Есть ли элегантное решение, которое является общим (работает для любого примитивного типа) и позаботится о дубликатах, возможно, с помощью linq?

Опять же для пояснения должны быть выполнены следующие условия:

1)Если одно (или несколько) из обязательных значений встречаются в списке аргументов несколько раз, выдается ошибка.Это учитывает только обязательные значения, другие значения могут встречаться несколько раз в списке аргументов.

2) Должно работать для любого примитивного типа данных

3) Возвращать ноль, если все требуемые значения встречаются ровно один раз.в списке аргументов.

4) Если в списке аргументов отсутствуют некоторые обязательные значения, возвращает список отсутствующих.

Ответы [ 3 ]

2 голосов
/ 16 июня 2019

Здесь вы хотите проверить два условия для списков.

  1. Если все требуемые элементы списка присутствуют в списке, вернуть null

  2. Если есть какие-либо пропущенные поля, то проверьте, что пропущенный список содержит дубликаты или нет.

    • Если есть дубликаты, выведите исключение
    • В противном случае верните список

Здесь вы идете со своей логикой

    // Except will give you list of elements from required list which are not present in arguments.
    var missing = required.Except(arguments); 

    // to return null we will check that missing list contains any value or not
    // if it is empty then retun null, which will satisfy your first condition
    if(!missing.Any()) 
        return null;
    else if(isDuplicate(arguments, required)) //Check for duplicates
         throw new Exception("Duplicate records");
    else
        return missing.Distinct().ToList(); //Else return distinct element from missing list.

Согласно вашему комментарию, если вы хотите проверить дубликаты в аргументе, тогда я добавил одну дополнительную функцию, которая будет возвращать логическое значение

public static bool isDuplicate(List<string> arguments, List<string> required)
{
    var group = arguments.GroupBy( i => i );
    foreach( var grp in group )
    {
        if(required.Contains(grp.Key) && grp.Count() > 1)
            return true;
    }
    return false;
}

POC: .Net Fiddle

1 голос
/ 16 июня 2019

Если вам нужно универсальное решение, я бы выбрал что-то вроде этого:

static List<T> FindMissingRequiredElements<T>(List<T> required, List<T> arguments)
{
    // convert to Dictionary where we store the required item as a key against count for an item
    var requiredDict = required.ToDictionary(k => k, v => 0);

    foreach(var item in arguments)
    {
        if (requiredDict.ContainsKey(item)) // now we check each item in arguments
        {
            requiredDict[item]++; // if we have required, adding to count
            if (requiredDict[item] > 1) // if we met required item more than once, throw exception
            {
                throw new Exception($"Required item {item} appeared more than once!");
            }
        }
    }

    var result = new List<T>();
    // now we are checking for missing items
    foreach (var key in requiredDict.Keys)
    {
        if (requiredDict[key] == 0)
        {
            result.Add(key);
        }
    }

    return result.Any() // if there are missing items, return the list, if not - return null
        ? result
        : null;
}

Ключевая идея здесь - использовать словарь для подсчета количества вхождений необходимых элементов в списке.

1 голос
/ 16 июня 2019

Попробуйте это

if(required.GroupBy(i => i).Any(g => g.Count > 1))
  throw new Exception("Duplicates found");
var missing = required.Except(arguments).ToList();
return missing.Lenght == 0 ? null : missing;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...