2011-03-25 14 views
5

Tengo una colección que representa la población (M, F) para cada año de edad.Para. Tomar() o no. Tomar(), esa es la pregunta

Para proyectar la población a través del tiempo, primero tengo que hacer los cálculos con las mujeres para que pueda calcular el porcentaje de hombres y mujeres recién nacidos en base a una constante estadística de masculinidad.

Dicho esto, tengo una primera matriz que contiene población masculina y femenina por año de edad.

// Where 1 is the evaluation Id and 2009 the year I want the 
// initial population information for. 
IList<AnnualPopulation> initialPopulation = 
    LoadMatrix<AnnualPopulation>(1, 2009); 

Ahora, con el fin de proyectar la población de mujeres en primer lugar, que utilice la siguiente:

IList<AnnualPopulation> initialWomenPopulation = (
     from w in initialPopulation 
     where String.Equals("F", w.Gender) 
     select w 
    ).FirstOrDefault(); 

Y tengo que tener en cuenta las tasas de mortalidad, tanto para el actual (año inicial (2009)) y la año para el cual deseo proyectar, del cual ya tengo las tasas de mortalidad para cada año de edad.

IList<AnnualDeathRate> deathRates = LoadMatrix<AnnualDeathRate>(1, 2009) 

Esto carga las tasas de desvanecimiento de 2009 y posteriores para cada año de edad. Por lo tanto, para considerar solo 2009 y 2010, digamos, utilicé el siguiente código Linq.

AnnualDeathRate[] femaleDeathRates = (
     from fdr in deathRates 
     where (string.Equals("F", fdr.Gender)) 
     select fdr 
    ).TakeWhile(dr => 
     initialWomenPopulation.Year == dr.Year || 
     dr.Year == initialWomenPopulation.Year + 1 
    ).ToArray() 

Preguntas

  1. ¿Hubiera sido mejor si hubiera utilizado .Take(2) junto con una where condición suplementaria de la dr.Year?
  2. ¿Hay mejores alternativas?
  3. ¿Mi enfoque vale la pena considerarlo?

Respuesta

1

En realidad, la # 1 puede producir un resultado diferente al código actual. Por ejemplo, si el orden fue aleatorio (no veo ningún orden en ninguna parte) el código actual puede devolver cualquier número de resultados (p. Ej., No hay resultados si el primer elemento no coincide con ninguna de las dos condiciones)

Parece que el enfoque # 1 sería más correcto (a menos que realmente desee el comportamiento de TakeWhile) Usted dice que quiere los primeros 2 resultados que coincidan con la condición dada, sean o no los primeros de la lista inicial.

Por ejemplo

var numbers = new[] {2, 3, 1, 4}; 
Console.WriteLine("TakeWhile"); 

foreach(var n in numbers.TakeWhile(x => x == 1 || x == 2)) 
{ 
    Console.Write(n); 
} 
Console.WriteLine(); 
Console.WriteLine(); 
Console.WriteLine("WhereTake2"); 

foreach (var n in numbers.Where(x => x == 1 || x == 2).Take(2)) 
{ 
    Console.Write(n); 
} 

Lienzo:

TakeWhile 
2 

WhereTake2 
21 
+0

+1 Para ilustrar el comportamiento del método 'TakeWhile'. Consideraré usar 'Take' en su lugar. Además de mi preocupación "Take()", me gustaría asegurarle al usuario que puede confiar en los índices "fix" para indexar las colecciones. Este es un proyecto de modernización de aplicaciones Fortran y el usuario se utiliza para usar índices y trabajar con matrices multidimensionales. Entonces, supongo que debería 'OrderBy' y' Take' después. ¿Mi lógica suena bien? –

+0

@Lo siento, creo que mi cerebro se ha salido todo el día porque su pregunta parece lógica, pero me cuesta imaginarme lo que quiere decir. – Davy8

1

que habría incluido la cláusula en su TakeWhile llamada en el where cláusula de la consulta, es que hay una razón por la que no lo hizo? A largo plazo, probablemente no haya mucha diferencia entre los dos, pero el TakeWhile parece innecesario y hace que su código sea más confuso, IMO.

+0

+1 nunca han pensado en ello de esta manera. La legibilidad es de hecho una cuestión de gran importancia aquí, ya que este código no será mantenido por personas de TI, sino por usuarios. ¡Gracias! –

+0

¿Mantenido por usuarios? Eso suena aterrador, ¡buena suerte! –

Cuestiones relacionadas