我有问题。我创建了这样的字典:
tblproperties("skip.header.line.count"="1")
使用这样的课程:
var TriangleRegistry = new Dictionary<string, TriangleRegistryObject>();
字典中充满了三角形的坐标。现在,我知道x1,y1,x2,y2,x3,y3,并且我想使用x1,y1,x2,y2,x3,y3获得直角三角形的class TriangleRegistryObject
{
public double x1 { get; set; }
public double y1 { get; set; }
public double x2 { get; set; }
public double y2 { get; set; }
public double x3 { get; set; }
public double y3 { get; set; }
public bool Selected { get; set; }
}
的值。
使用所有6个值找到第7个值很重要,因为我有很多三角形!
有人可以帮我吗?
答案 0 :(得分:0)
如果您要存储和检索字典中的内容,并且键由三角形的所有三个坐标(六个值)组成,则三角形的组合坐标是的键字典。
这就是您在这里描述的内容:
我知道x1,y1,x2,y2,x3,y3,我想使用x1,y1,x2,y2,x3,y3来获取直角三角形的选定值。
(我回避了Dictionary<TriangleRegistryObject, bool>
是否有意义的问题,而侧重于如何将三角形的点用作键。)
假设您实际上创建了一个Dictionary<TriangleRegistryObject, bool>
,其中键是一个三角形,而值是一个布尔值,指示是否已选择它。挑战仍然是,为了确定键是否重复,字典将使用引用相等性。 TriangleRegistryObject
的两个具有相同坐标的不同实例可以是两个键,这可能不是您想要的。
我们需要告诉字典如何比较两个三角形。我们可以通过在Equals
上覆盖GetHashCode
和TriangleRegistryObject
来做到这一点。但是我们不必更改类以满足这种比较的需要,我们只需告诉此特定词典如何比较三角形即可(尽管这可能也是一个很好的解决方案。)
首先,我们将创建IEqualityComparer<TriangleRegistryObject>
的自定义实现:
public class TriangleComparer : IEqualityComparer<TriangleRegistryObject>
{
public bool Equals(TriangleRegistryObject x, TriangleRegistryObject y)
{
return x.x1.Equals(y.x1)
&& x.y1.Equals(y.y1)
&& x.x2.Equals(y.x2)
&& x.y2.Equals(y.y2)
&& x.x3.Equals(y.x3)
&& x.y3.Equals(y.y3);
}
public int GetHashCode(TriangleRegistryObject obj)
{
unchecked
{
var hashCode = obj.GetHashCode();
hashCode = (hashCode * 397) ^ obj.GetHashCode();
hashCode = (hashCode * 397) ^ obj.GetHashCode();
hashCode = (hashCode * 397) ^ obj.GetHashCode();
hashCode = (hashCode * 397) ^ obj.GetHashCode();
hashCode = (hashCode * 397) ^ obj.GetHashCode();
return hashCode;
}
}
}
(好吧,这看起来并不那么简单。我实际上被骗了,让Resharper帮助我生成所有内容。)
现在,如果我们要使用三角形作为字典中的键,则只需在创建字典时指定比较器即可:
var dictionary = new Dictionary<TriangleRegistryObject, bool>(new TriangleComparer());
现在,字典将按照我们告诉它的方式比较键,而不是使用引用相等。
或者,如果您只是想将等式比较直接添加到三角形本身中,而不是使用自定义比较器,则可以执行此操作(该方法省去了Selected
属性):
public class TriangleRegistryObject
{
public double x1 { get; set; }
public double y1 { get; set; }
public double x2 { get; set; }
public double y2 { get; set; }
public double x3 { get; set; }
public double y3 { get; set; }
public override bool Equals(object obj)
{
return base.Equals(obj);
}
protected bool Equals(TriangleRegistryObject other)
{
return x1.Equals(other.x1)
&& y1.Equals(other.y1)
&& x2.Equals(other.x2)
&& y2.Equals(other.y2)
&& x3.Equals(other.x3)
&& y3.Equals(other.y3);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = x1.GetHashCode();
hashCode = (hashCode * 397) ^ y1.GetHashCode();
hashCode = (hashCode * 397) ^ x2.GetHashCode();
hashCode = (hashCode * 397) ^ y2.GetHashCode();
hashCode = (hashCode * 397) ^ x3.GetHashCode();
hashCode = (hashCode * 397) ^ y3.GetHashCode();
return hashCode;
}
}
}
还有一个问题:三角形的点可能不会改变。如果他们可以改变,那么坏事就可能发生。假设您有两个不同的点用作键,然后将一个点更改为与另一个点相同。然后,您将有重复的密钥,这很不好。
为防止这种情况,您将使三角形类不可变,以便将值传递给构造函数,并且永远不能更改。
仅介绍基础知识,因为我不知道您的应用程序的任何细节:如果您的三角形是一个结构而不是一个类,并且其所有成员都是值类型,那么将使用值进行比较。如果唯一的值是点(删除Selected
),则两个具有相同点的实例将被视为相等,并且不需要所有额外的比较代码。您仍然希望使该结构不可变。
答案 1 :(得分:0)
您可以使用LINQ(如上/下所述)或对每个循环进行此操作,并检查洗涤变量。在大多数情况下,LINQ的速度要慢得多,因此,如果您的应用程序需要更好的性能,请考虑将其用于/等。
答案 2 :(得分:-1)
您可以使用LINQ查询字典并找到匹配项:
using System.Linq;
...
var matches = TriangleRegistry.Where(t => t.Value.X1 == ... && t.Value.Y1 == ...); // fill in the blanks here with whatever you're looking for
foreach (var match in matches)
{
Console.WriteLine("Here's a match: {0}", match.Selected);
}