2012-03-27 14 views
6

hoLINQ, creando collezione unica di una collezione

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 e Vertexes sono raccolti in liste

Qualche esempio:

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 

Così mi piacerebbe fare IDictionary<Edge, bool> che avrebbe tenere i bordi (A -> B e B -> A sarebbe come 1), e bool - se è bidirezionale o no.

Ne ho bisogno perché quando li disegna ora, disegna 2 frecce una sotto l'altra. Farei meglio 1 freccia.

Quindi sono piuttosto bloccato qui ... Qualcuno può aiutarmi un po '?

+1

Si prega di mostrare definizione della Edge e classi Vertex – sll

risposta

2

Penso che si dovrebbe implementare l'interfaccia IEquatable per la classe Edge:

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

e aggiungi il tuo bordi per una collezione HashSet<Edge>. Quindi puoi chiamare il suo metodo Contains per verificare se contiene il bordo o meno.

EDIT: come Henk ha detto, è anche possibile implementare una classe personalizzata 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()); 
    } 
} 

e inizializzare il vostro hashset con

_drawableEdges = new HashSet<Edge>(EdgeComparer.Default); 
+0

o scrivere un comparatore separato per eseguire la stessa logica. Fornire anche un modo simmetrico per combinare HashCodes –

+0

Si potrebbe voler sostituire '==' con 'Equals' per evitare i problemi' NaN'. E ovviamente l'OP deve implementare 'Equals',' == ','! = 'E' GetHashCode() ' – CodesInChaos

+1

@HenkHolterman True, ho aggiunto anche GetHashCode(). –

2

Presumo che la classe Edge abbia un costruttore che occupa 2 vertici. Vedi sotto per una possibile idea (non l'ho compilato, ma spero che tu abbia capito l'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 
    } 
} 
+0

dieci secondi più veloce sul sorteggio di me, avere un upvote. –

+0

voi, di base, mi serviva solo l'idea – Wish