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。

我需要它,因为当我现在画它们时,它会画出两个箭头。我最好做一支箭。

所以我很困在这里。。。有人能帮我一点忙吗?

LINQ,创建一个独特的集合

我认为您应该为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
    }
}