LINQ,创建一个独特的集合
本文关键字:一个 集合 创建 LINQ | 更新日期: 2023-09-27 18:29:21
我有
class Vertex{
Graph _graph;
float x;
float y;
string key;
//and some similar atributes
public IEnumerable<Edge> Edges{
get{
return _graph.Edges.Where(s => s.Source == this);
}
}
}
class Edge{
Graph _graph;
Vertex source;
Vertex target;
}
class Graph
{
private VertexCollection _vertexCollection; // extends List<Vertex>
private EdgeCollection _edgeCollection; //extends List<Edge>
public IEnumerable<Vertex> Vertexes
{
get
{
return _vertexCollection;
}
}
public IEnumerable<Edge> Edges
{
get
{
return _edgeCollection;
}
}
public IDictionary<Edge, bool> DrawableEdges
{
get
{
//want to return my uniq dictionary
}
}
CCD_ 1和CCD_
例如:
A-->B // edge from vertex A to B
B-->C // edge from vertex B to C
C-->A // edge from vertex C to A
A-->C // edge from vertex A to C -- this is two way edge
所以我想做IDictionary<Edge, bool>
,它会保持边(A-->B和B-->A会像1),如果是双向或否,则为bool。
我需要它,因为当我现在画它们时,它会画出两个箭头。我最好做一支箭。
所以我很困在这里。。。有人能帮我一点忙吗?
我认为您应该为Edge
类实现IEquatable
接口:
public class Edge : IEquatable<Edge>
{
...
public bool Equals(Edge other)
{
return (
(other.Source == this.Source && other.Target == this.Target) ||
(other.Target == this.Source && other.Source == this.Target));
}
public override int GetHashCode()
{
return (Source.GetHashCode() ^ Target.GetHashCode());
}
}
并将您的边添加到HashSet<Edge>
集合中。然后可以调用它的Contains
方法来检查它是否包含边。
编辑:正如Henk所说,您还可以实现自定义IEqualityComparer
类:
public sealed class EdgeComparer : IEqualityComparer<Edge>
{
public static EdgeComparer Default { get; private set; }
static EdgeComparer()
{
Default = new EdgeComparer();
}
private EdgeComparer()
{
}
public bool Equals(Edge x, Edge y)
{
return (
(x.Source == y.Source && x.Target == y.Target) ||
(x.Target == y.Source && x.Source == y.Target));
}
public int GetHashCode(Edge edge)
{
return (edge.Source.GetHashCode() ^ edge.Target.GetHashCode());
}
}
并使用初始化您的哈希集
_drawableEdges = new HashSet<Edge>(EdgeComparer.Default);
我假设Edge类有一个接受2个顶点的构造函数。请参阅下面的可能想法(我还没有编译这个,但希望你能理解这个想法)。
foreach(Edge edge in Edges)
{
Edge edge2 = new Edge(edge.V2, edge.V1);
if (!dict.ContainsKey(edge) && !dict.ContainsKey(edge2))
{
dict[edge] = false; // first time we've seen this edge, so put it in dictionary
}
else if (!dict.ContainsKey(edge) && dict.ContainsKey(edge2))
{
dict[edge2] = true; // a bidirectional edge
}
}