答案 0 :(得分:3)
一种避免使用Int32.MaxValue
作为基准并且避免在未找到结果的情况下返回0
的方法是使用Nullable<int>
或速记int?
public static int? GetMin(string key, List<Dictionary<string, int>> db)
{
int? result = null;
if (db != null) {
foreach (var dic in db) {
if (dic.TryGetValue(key, out int value) && (result == null || value < result)) {
result = value;
}
}
}
return result;
}
如果返回null
,则表示未找到匹配项。如果您更喜欢使用int
作为返回类型并在这种情况下返回0
,请写。
return result ?? 0;
在方法内部使用可为null的int仍然有用,因为它使我们避免滥用Int32.MaxValue
。现在Int32.MaxValue
可以是有效的输入和结果。
循环没有错。并非所有内容都需要使用LINQ。如果要使用LINQ,请确保使用Min
重载与可为null配合使用。非空变量会为空输入引发异常。枚举字典(使用SelectMany
)的LINQ变体没有利用快速字典查找的优点,并且效率不高。
public static int? GetMinLINQ(string key, List<Dictionary<string, int>> db)
{
if (db == null) {
return null;
}
return db
.Select(d => (isMatch: d.TryGetValue(key, out int i), result:i))
.Where(x => x.isMatch)
.Select(x => (int?)x.result)
.Min();
}
它将TryGetValue
的返回值和out
变量组合成一个值元组。但是最终的方法并不比使用循环的方法短。
答案 1 :(得分:0)
您可以编写一个函数,以检查key
在词典中是否可用。
如果字典中包含键,则从中返回Min
,如果不存在则返回0
实施:
public static int GetMinFromDictionaryList(List<Dictionary<string, int>> parameter, string key)
{
var keyValuePairList = parameter.SelectMany(d => d).Select(x => x.Key);
if (keyValuePairList.Contains(key))
{
return parameter.SelectMany(d => d).Where(x => x.Key == key).ToList().Min(x => x.Value);
}
return 0;
}
POC:.NetFiddle
答案 2 :(得分:0)
我不明白问题出在哪里,这应该很简单。
请参见以下示例。
public static void Main()
{
var db = new List<Dictionary<string, int>>()
{
new Dictionary<string, int>(){ {"a", 1 }, { "b", 5 }, { "c", 3 } },
new Dictionary<string, int>(){ {"d", 5 }, { "b", 3 } },
new Dictionary<string, int>(){ {"a", 2 }, { "c", 2 } },
};
// Result you will get is 1
Console.Write(GetMin(db, "a").ToString());
}
public static int GetMin(List<Dictionary<string, int>> db, string key)
{
return db == null || !db.Any(x=> x.ContainsKey(key)) ? 0 :
db.SelectMany(x=> x).Where(x=> x.Key == key).Select(x=> x.Value).Min();
}
答案 3 :(得分:0)
由于LINQ查询中的唯一问题是在集合为空(未找到匹配键,因此引发异常)时评估最小值,因此将DefaultIfEmpty放在 {{1} } 允许在 Min()
过滤器未返回任何元素时简单地返回0
。
不需要使用可为空的变量或预先过滤:
Where()
答案 4 :(得分:0)
您可以将其编写为LINQ方法的一个序列。
因此,您有一个字符串key
和一系列相似的字典,每个字典都是一个Dictionary<string, int>
。并且您想要字典键等于“键”的最低整数值。如果所有项目都不包含Key
,则要返回零。
很幸运,Dictionary<string, int>
实现了IEnumerable<KeyValuePair<string, int>>
,因此您可以使用SelectMany
,Where
,Select
和Aggregate
string key = ...
List<Dictionary<string, int>> myListOfDictionaries = ...
// note: this implements IEnumerable<IEnumerable<KeyValuePair<string, int>>>
// so a sequence of sequences of KeyValuePairs
var smallestIntThatHasKey = myListOfDictionaries
// make one list containing all keyValuePairs
.SelectMany(dictionary => dictionary)
// result: one sequence of KeyValuePairs
// keep only those KeyValuePairs where the Key equals key
.Where(keyValuePair => keyValuePair.Key == key)
从结果序列中,我想要一个值最小的序列。我可以按降序对所有值进行排序,并采用第一个值:
.Select(keyValuePair => keyValuePair.Value)
.OrderBy(value => value)
.FirstOrDefault();
如果没有带钥匙的物品,这将正确返回零。这也不是一个非常聪明的解决方案:如果您按排序顺序找到了第一个元素(最小的),那么,如果仅使用第一个,那么为什么还要对第二个,第三个等进行排序。更好地使用Aggregate
:
.Select(keyValuePair => keyValuePair.Value)
.Aggregate(0,(minValue, enumeratedValue) =>
(enumeratedValue < minValue) ? enumeratedValue : minValue);
这将使汇总结果的种子为零。它将只传递一个序列:它将检查带有枚举值的minValue并将最小的一个保留为汇总值