2012-03-27 41 views
6

tengoLINQ, creando colección única de una colección

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 y Vertexes se recogen en listas

Algunos ejemplos:

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 

lo que me gustaría hacer IDictionary<Edge, bool> lo cual mantener los bordes (A -> B y B -> A sería como 1), y bool - si es de dos vías o no.

Lo necesito porque cuando los dibujo ahora, dibuja 2 flechas una debajo de la otra. Mejor haré 1 flecha.

Así que estoy bastante atrapado aquí ... ¿Alguien me puede ayudar un poco?

+1

favor mostrar definición del borde y las clases Vertex – sll

Respuesta

2

creo que debe implementar la interfaz IEquatable para su clase 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()); 
    } 
} 

y añadir sus bordes a una colección HashSet<Edge>. Luego puede llamar al método Contains para verificar si contiene el borde o no.

EDIT: como Henk dijo, también se puede aplicar una clase personalizada 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 inicializar su hashset con

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

O escriba una Comparer por separado para realizar la misma lógica. También proporcione una forma simétrica para combinar HashCodes –

+0

. Es posible que desee reemplazar '==' con 'Igual' para evitar los problemas' NaN'. Y, por supuesto, el OP necesita implementar 'Equals',' == ','! = 'Y' GetHashCode() ' – CodesInChaos

+1

@HenkHolterman Cierto, también he agregado GetHashCode(). –

2

Supongo que su clase Edge tiene un constructor que toma 2 vértices. Vea a continuación la posible idea (no he compilado esto, pero espero que entienda la 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

diez por segundos más rápido en el sorteo que yo, tener un voto favorable. –

+0

ye, basicley yo solo necesitaba la idea – Wish

Cuestiones relacionadas