Operadores de LINQ: Partitioning

Tabla de contenidos:

Skip

El operador Skip nos sirve para ignorar los X primeros elementos de una secuencia.

Código necesario para los ejemplos:

Una lista de nombres:

List<string> nombres = new List<string>
		   {
			   "Jesus",
			   "Alvaro",
			   "Manolo",
			   "Juan",
			   "Paco",
			   "Rosi",
			   "Maria",
			   "Amanda",
			   "Julia"
		   };

Volver al operador Skip

Skip:

public static IEnumerable<TSource> Skip<TSource>(
	this IEnumerable<TSource> source,
	int count
)

Skip toma como argumento un número que será la cantidad de elementos de la secuencia a ignorar. Devuelve una enumeración con los elementos restantes.

Teniendo la lista de nombre, queremos saltarnos los 5 primeros para asi quedarnos con los nombres de mujer:

IEnumerable<string> mujeres = nombres.Skip(5);

El resultado sería:

Rosi
Maria
Amanda
Julia

Si como argumento le pasamos un cero o un número negativo, no ignorará nada.

Volver a la tabla de contenidos

SkipWhile

El operador SkipWhile como su homónimo Skip sirve para ignorar elementos. Pero dada una condición y no un número.

Código necesario para los ejemplos:

Una lista de calificaciones:

List<double> notas = new List<double>
	   {
		   0, 1.2, 2, 3, 4.5, 4.9, 6, 6, 7.6, 9, 10
	   };

Volver al operador SkipWhile

SkipWhile estandar:

public static IEnumerable<TSource> SkipWhile<TSource>(
	this IEnumerable<TSource> source,
	Func<TSource, bool> predicate
)

SkipWhile toma un delegado el cual recibe el elemento de la secuencia y devuelve un bool. El operador devuelve una enumeración con los elementos no ignorados.

Cada elemento irá pasando por el delegado y devolverá true o false dependiendo de una condición. Mientras vaya devolviendo true, esos elementos se irán ignorando. Lo importante de esto es que cuando uno de los elementos devuelva false, se devuelve ese elemento y los restantes de la secuencia sin comprobarlos.

Este operador se suele usar con los operadores de ordenación, pero puesto que prefiero mostrar ejemplos que involucren la menor cantidad de operadores posibles, vamos a probar con una lista ya ordenada a mano.

Imaginemos que nuestra condición es ir ignorando toda calificación considerada suspendida hasta que encontremos una aprobada:

IEnumerable<double> aprobados = notas.SkipWhile(nota => nota < 5);

Aquí la condición es sencilla, ignorar toda nota que sea menor a 5. Como veis es importante que la secuencia a tratar esté ordenada puesto que a la minima que encuentre una nota mayor a 5 dejará de hacer comprobaciones y meterá en la enumeración todas las notas restantes estén aprobadas o no.

El resultado es:

6
6
7.6
9
10

Volver al operador SkipWhile

SkipWhile + índice:

public static IEnumerable<TSource> SkipWhile<TSource>(
	this IEnumerable<TSource> source,
	Func<TSource, int, bool> predicate
)

En esta sobrecarga, el delegado además del elemento, recibe también el indice de dicho elemento en la secuencia. Lo cual nos dá mas posibilidades a la hora de ignorar elementos.

Como antes, es difícil mostrar el uso de esta sobrecarga sin encadenarla a otros operadores, pero como la sencillez es lo más importante a la hora de aprender, vamos con este ejemplo:

IEnumerable<double> variasNotas = notas.SkipWhile((nota, index) => nota < index + 0.5);

Estamos ignorando todas las notas hasta que una de ellas sea más alta que su indice + 0.5.

Así que el resultado es:

4,5
4,9
6
6
7,6
9
10

Volver a la tabla de contenidos

Take

El operador Take es justo lo contrario al operador Skip. Tomará aquellos X primeros elementos de una secuencia e ignorará el resto.

Código necesario para los ejemplos:

Una lista de nombres:

List<string> nombres = new List<string>
		   {
			   "Jesus",
			   "Alvaro",
			   "Manolo",
			   "Juan",
			   "Paco",
			   "Rosi",
			   "Maria",
			   "Amanda",
			   "Julia"
		   };

Volver al operador Take

Take:

public static IEnumerable<TSource> Take<TSource>(
	this IEnumerable<TSource> source,
	int count
)

Take toma como argumento un número que será la cantidad de elementos de la secuencia a devolver. Devuelve una enumeración con dichos elementos ignorando el resto.

En este caso, si necesitamos los 5 primeros nombres, haríamos algo así:

IEnumerable<string> hombres = nombres.Take(5);

Esto imprimiría:

Jesus
Alvaro
Manolo
Juan
Paco

Si le pasamos un numero negativo o cero, no devolverá nada.

Volver a la tabla de contenidos

TakeWhile

El operador TakeWhile como su homónimo Take sirve para devolver los elementos de una secuencia pero en este caso los irá devolviendo mientras una condición devuelva true.

Código necesario para los ejemplos:

Una lista de calificaciones:

List<double> notas = new List<double>
	   {
		   0, 1.2, 2, 3, 4.5, 4.9, 6, 6, 7.6, 9, 10
	   };

Volver al operador TakeWhile

TakeWhile estandar:

public static IEnumerable<TSource> TakeWhile<TSource>(
	this IEnumerable<TSource> source,
	Func<TSource, bool> predicate
)

TakeWhile toma un delegado el cual recibe el elemento de la secuencia y devuelve un bool. El operador devuelve una enumeración con los elementos no ignorados.

Cada elemento irá pasando por el delegado y devolverá true o false dependiendo de una condición. Mientras devuelva true, los elementos se irán devolviendo. Lo importante de esto es que cuando uno de los elementos devuelva false, se ignorará ese elemento y los restantes de la secuencia sin comprobarlos.

Este operador se suele usar con los operadores de ordenación, pero puesto que prefiero mostrar ejemplos que involucren la menor cantidad de operadores posibles, vamos a probar con una lista ya ordenada a mano.

Vamos a coger todas las notas suspensas (para regañar a aquellos que no aprobaron :P ):

IEnumerable<double> suspensos = notas.TakeWhile(nota => nota < 5);

Mientras la nota sea menor a 5, ir devolviendola. Cuando una sea mayor, ignorar el resto de la secuencia.

El resultado es:

0
1.2
2
3
4.5
4.9

Volver al operador TakeWhile

TakeWhile + índice:

public static IEnumerable<TSource> TakeWhile<TSource>(
	this IEnumerable<TSource> source,
	Func<TSource, int, bool> predicate
)

En esta sobrecarga, el delegado además del elemento, recibe también el indice de dicho elemento en la secuencia. Lo cual nos da mas posibilidades a la hora de devolver elementos.

IEnumerable<double> variasNotas = notas.TakeWhile((nota, index) => nota < index + 0.5);

Mientras la nota sea menor al valor del índice + 0.5, añadirla a la enumeración.

Volver a la tabla de contenidos

Tags:

Un comentario

Dejar un comentario