2010-03-26 12 views
6

Estoy tratando de normalizar las cadenas arbitrarias de .Skip() y .Take() llamadas a una sola llamada .Skip() seguido de una sola opcional .Take() llamada.cadenas de Normalización de Saltee() y .Tomar() llama

Éstos son algunos ejemplos de los resultados esperados, pero no estoy seguro de si estos son correctos:

.Skip(5)      => .Skip(5) 
.Take(7)      => .Skip(0).Take(7) 

.Skip(5).Skip(7)    => .Skip(12) 
.Skip(5).Take(7)    => .Skip(5).Take(7) 
.Take(7).Skip(5)    => .Skip(5).Take(2) 
.Take(5).Take(7)    => .Skip(0).Take(5) 

.Skip(5).Skip(7).Skip(11)  => .Skip(23) 
.Skip(5).Skip(7).Take(11)  => .Skip(12).Take(11) 
.Skip(5).Take(7).Skip(3)  => .Skip(8).Take(4) 
.Skip(5).Take(7).Take(3)  => .Skip(5).Take(4) 
.Take(11).Skip(5).Skip(3)  => .Skip(8).Take(3) 
.Take(11).Skip(5).Take(7)  => .Skip(5).Take(6) 
.Take(11).Take(5).Skip(3)  => .Skip(3).Take(2) 
.Take(11).Take(5).Take(3)  => .Skip(0).Take(3) 

Alguien puede confirmar estos son los resultados correctos se pueden esperar?


Aquí está el algoritmo básico que deriva de los ejemplos:

class Foo 
{ 
    private int skip; 
    private int? take; 

    public Foo Skip(int value) 
    { 
     if (value < 0) 
      value = 0; 

     this.skip += value; 

     if (this.take.HasValue) 
      this.take -= value; 

     return this; 
    } 

    public Foo Take(int value) 
    { 
     if (value < 0) 
      value = 0; 

     if (!this.take.HasValue || value < this.take) 
      this.take = value; 

     return this; 
    } 
} 

Alguna idea de cómo puedo confirmar si este es el algoritmo correcto?

+0

Por curiosidad, ¿para qué se utiliza? –

+0

@NickLarsen: estoy implementando un proveedor de consultas LINQ y necesito transformar las llamadas saltarse y recibir en un solo par desplazamiento/recuento. – dtb

+3

No estoy seguro de cómo se comportan, pero siguiendo la supuesta lógica que creo que debería tener .Skip (5) .Tomar (7) .Tomar (3) => .Skip (5) .Tomar (3) (es decir, tomar 3 y no 4). Su código también parece dar este valor, que creo que es correcto – rslite

Respuesta

4

Este es un escenario perfecto para TDD. Dado que ha definido su especificación anterior, debe ser cake para implementar como una serie de solo un par de pruebas.

"Correcto" es bastante subjetivo, pero esos ejemplos parecen cuerdos.

Además, yo normalizaría las llamadas .Skip(0).

Asegúrese de definir claramente las cajas de borde. Por ejemplo,

.Take(11).Skip(12).Take(1) 

probablemente se debe normalizar en una edición .Take(0)


:

La definición oficial de salto:

no pasa por un número determinado de elementos en una secuencia y luego devuelve los elementos restantes.

y tomar:

devuelve un número especificado de elementos contiguos desde el principio de la secuencia.

Según sus ejemplos, creo que sus casos de prueba están siguiendo las especificaciones.

+0

El problema no es tanto implementar mi propia especificación, sino encontrar la especificación "correcta", ya que no estoy desarrollando mi propio marco de consulta sino que me conecto a LINQ. ¿Hay alguna documentación oficial sobre cómo deberían comportarse las implementaciones LINQ Skip/Take? – dtb

+0

Correcto, la documentación no es realmente explícita sobre cómo se deben evaluar las cadenas, pero de esas especificaciones acepto que mis casos de prueba (que derivé de la intuición) parecen sanos. Supongo que tendré que inventar más casos de prueba para detectar todos los casos extremos y actualizar el algoritmo en consecuencia. – dtb

Cuestiones relacionadas