switch - repetir ciclos c#
Llamando a los codiciosos compañeros de código: ¿alternativas a los bucles anidados? (8)
No es raro para mí (o probablemente para cualquier otra persona) tener una lista de objetos que necesito para iterar y luego interactuar con una lista de propiedades. Yo uso un ciclo anidado, como este:
IList<T> listOfObjects;
IList<TProperty> listOfProperties;
foreach (T dataObject in listOfObjects)
{
foreach (TProperty property in listOfProperties)
{
//do something clever and extremely useful here
}
}
¿Es este el patrón de tiempo y rendimiento probado para este problema? ¿O hay algo más divertido, más elegante o simplemente divertido (mientras se puede leer y mantener, por supuesto)?
El código de arriba no me hace sonreír. ¿Alguien puede por favor ayudar a traer algo de alegría a mi loop?
¡Gracias!
Actualización: uso el término "nerd" en el sentido más positivo. Como parte de la definición de wikipedia, "eso se refiere a una persona que realiza actividades intelectuales con pasión". ¡Por "codicioso" me refiero a alguien que está preocupado por mejorarse continuamente como programador, encontrando nuevas, novedosas y elegantes formas de codificación que son rápidas, fáciles de mantener y hermosas! Se regocijan por haberse mudado de VB6 y quieren que las personas inteligentes critiquen su código y los ayuden a actualizarse. (Nota: también les gusta hacer nuevas palabras que terminan en -ify).
Nota final:
Gracias a Dave R, Earwicker y TheSoftwareJedi por enviarme por el camino de Linq. ¡Es el tipo de código feliz que estaba buscando!
Ciertamente, no hay nada de malo con los bucles anidados. Son rápidos, fáciles de leer y han existido desde que el desarrollo de software dio sus primeros pasos.
Como quiera realizar acciones mientras itera sobre una colección, puede encontrar que LINQ sería una avenida interesante para explorar:
http://msdn.microsoft.com/en-us/vcsharp/aa904594.aspx
Se limitará a versiones posteriores del Framework (3.5 en adelante), pero en realidad puede encontrar el enfoque de Programación Funcional bastante elegante. Otras características del lenguaje que entran en juego cuando vas por este camino incluyen lambdas y métodos anónimos, que son fascinantes por derecho propio.
La mejor de las suertes y espero que te diviertas en el camino, ese es un gran enfoque :)
En tal escenario, a menudo comenzamos por filtrar las piezas que nos interesan. Su bloque dosomethingclever () generalmente comienza en
foreach (T dataObject in listOfObjects)
{
foreach (TProperty property in listOfProperties)
{
if (property.something == "blah")
{ // OK, we found the piece we''re interested in...
// do something clever...
}
}
}
Aquí es donde LINQ es tu amigo, permitiéndote reemplazar tus loops por una declaración seleccionada. Por supuesto, es posible que aún necesite iterar en el conjunto de resultados.
Parece que intenta unir cartesianamente dos listas y aplicar una cláusula where. Aquí hay un ejemplo simple que muestra la sintaxis de Linq para hacer esto, que creo que es lo que está buscando. list1 y list2 pueden ser IEnumerable, tu cláusula where puede contener una lógica más detallada, y en tu cláusula de selección puedes eliminar lo que necesites.
var list1 = Enumerable.Range(1, 100);
var list2 = Enumerable.Range(1, 100);
foreach (var item in from a in list1
from b in list2
where a % b == 0
select new { a, b })
{
Console.WriteLine(item);
};
El rendimiento será idéntico al que publicaste sin embargo, sin deseo de engañar con respecto a eso. Prefiero esta sintaxis Linq.
Si necesita hacer algo con cada objeto y cada propiedad, no hay mucho por hacer. Es posible que pueda hacer algunas cosas sintácticamente agradables, pero no hay una forma de hacer el trabajo.
Si solo está trabajando en un subconjunto de los objetos y / o propiedades, filtúelo (con linq a los objetos, si está haciendo .net 3.5).
Puede disfrutar de Filter / Map / Reduce para sus sets como un medio para introducir una mejor sintaxis para hacer operaciones de conjunto.
foreach (var pair in from obj in listOfObjects
from prop in listOfProperties
select new {obj, prop})
{
Console.WriteLine(pair.obj + ", " + pair.prop);
}
Me gustan las tuberías y filtros de Ayende, pero es mucho más código que LINQ incorporado para bucles simples (supongo que el ejemplo de código en la pregunta era trivial).
Si bien me gusta la elegancia de las soluciones de Linq, creo que mi recomendación sería extraer el bucle interno en un método; Tu código terminaría luciendo algo así como:
foreach(dataObject in listOfObjects)
DoSomethingCleverWithProperties(dataObject, listOfProperties);
Eso me parece más fácil de mantener.
Action<T, TProp> somethingClever = //your clever method
listOfObjects
.SelectMany(
o => listOfProperties,
(o, p) => new {o, p})
.ToList()
.ForEach(x => somethingClever(x.o, x.p));