判断字典对中的所有值是否相等
本文关键字:是否 字典 判断 | 更新日期: 2023-09-27 18:15:22
我有一个由点和力组成的字典,像这样:
public Dictionary<Point, Force> PointForceSet;
我想写一个函数,告诉我所有的力是否相同。到目前为止,我有这个:
public bool IsUniform()
{
foreach (var item in PointForceSet)
{
//?
}
}
确定键值对中的所有值是否相等的最简单方法是什么?
如果您的值有有意义的默认比较器(如数字),这就足够了:
public bool IsUniform()
{
return PointForceSet.Values.Distinct().Count() == 1;
}
但是,如果有类(如您的Force
),请记住覆盖GetHashCode
和Equals
,以允许真正区分Force
对象实例,例如:
class Force
{
public int X;
public int Y;
public override bool Equals(object obj)
{
Force other = obj as Force;
return other != null && X == other.X && Y == other.Y;
}
public override int GetHashCode()
{
return 17 * X + Y;
}
}
您可以使用LINQ提取第一个值,并检查以确保其他值都匹配:
public bool IsUniform()
{
var values = PointForceSet.Values;
if (values.Count == 0)
return false; // Normally would be true - handling your req. based on comments
var first = values.First();
return values.Skip(1).All(v => v.Equals(first));
}
你应该调用
PointForceSet.Distinct()
传入
IEqualityComparer<KeyValuePair<Point, Force>>
执行。
如果字典中有条目,而. distinct()只返回一个条目,根据比较器代码,所有条目都是"相同的"。
为了允许在发现非相等对时立即短路,理想的解决方案是简单地遍历序列,将每一项与第一项进行比较。
public static bool AreSame<T>(this IEnumerable<T> source,
IEqualityComparer<T> comparer)
{
comparer = comparer ?? EqualityComparer<T>.Default;
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
return true;
var first = iterator.Current;
while (iterator.MoveNext())
if (!comparer.Equals(first, iterator.Current))
return false;
return true;
}
}
请注意,使用迭代器的显式枚举既可以防止序列多次迭代,也可以支持空序列。
另一种使用HashSet<Force>
:
public bool IsUniform(ICollection<Force> forces)
{
if (forces == null) throw new ArgumentNullException("forces");
if (!forces.Any()) return false;
var set = new HashSet<Force> { forces.First() };
return set.SetEquals(forces);
}
// ...
bool allEqual = IsUniform(PointForceSet.Values);
可以工作,因为你已经覆盖了Equals
+ GetHashCode
的注释
如果Force
类覆盖Equals
和GetHashCode
方法,这应该可以工作。否则,实现IEqualityComparer
并将其传递给构造函数
public bool IsUniform()
{
return new HashSet<Force>(PointForceSet.Values).Count == 1;
}