Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ, creating unique collection of a collection

I have

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
        }
    }    

Edges and Vertexes are collected into lists

Some example:

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

So I would like to make IDictionary<Edge, bool> which would hold edges (A-->B and B-->A would be like 1), and bool - if it is two way or no.

I need it because when I draw them now, it draws 2 arrows under one another. I would better make 1 arrow.

So I'm pretty stuck right here... May anybody help me a bit ?

like image 968
Wish Avatar asked Mar 27 '12 17:03

Wish


1 Answers

I think you should implement the IEquatable interface for your Edge class:

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());
    }
}

and add your edges to a HashSet<Edge> collection. Then you can call its Contains method to check if it contains the edge or not.

EDIT: like Henk said, you can also implement a custom IEqualityComparer class:

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());
    }
}

and initialize your hashset with

_drawableEdges = new HashSet<Edge>(EdgeComparer.Default);
like image 195
Balazs Tihanyi Avatar answered Oct 13 '22 08:10

Balazs Tihanyi