假设我们得到两个列表(可以是任何原始类型):
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)如果所有必需值在参数列表中恰好出现一次,则返回null。
4)如果参数列表中缺少某些必需的值,则返回缺失值的列表。
答案 0 :(得分:2)
您要在此处根据列表检查两个条件。
如果列表中存在所有必需的列表元素,则返回null
如果缺少任何字段,请检查缺少的列表是否包含重复项。
您在这里顺理成章
// 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 :(得分:1)
尝试一下
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;
答案 2 :(得分:1)
如果您需要一个通用的解决方案,我会选择这样的东西:
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;
}
这里的关键思想是使用“字典”来计算列表中我们出现了多少项必需项。