LINQ, creating a unique collection 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 Vertexes

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 an IDictionary<Edge, bool> that will hold the edges (A β†’ B and B β†’ A will be like 1), and bool if these are two paths or not.

I need this because when I draw them now, he draws 2 arrows under each other. I would rather do 1 arrow.

So, I'm pretty stuck here ... Can someone help me a little?

+6
source share
2 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 edges to the HashSet<Edge> collection. You can then call its Contains method to check if it contains an edge or not.

EDIT: as Henk said, you can also implement your own 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); 
+2
source

I assume that your Edge class has a constructor that takes 2 vertices. The following is a possible idea (I did not compile this, but hope you get this idea).

 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 } } 
+2
source

Source: https://habr.com/ru/post/911780/


All Articles