开发者

To .Take() or not to .Take(), that is the question

I have a collection that represents the population (M, F) for each years of age.

In order to project populatio开发者_如何转开发n through time, I have to first make the calculations with the women so that I may calculate the percentage of new born men and women based on a statistical constant of masculinity birth rate.

That said, I have a first matrix which contains both men and women population per year of age.

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

Now, in order to project the women's population first, I use the following:

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

And I have to consider mortality rates for both the current (initial year (2009)) and the year for which I wish to project, from which I already have mortality rates for each year of age.

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

This loads the deather rates from 2009 and later for each year of age. Hence, in order to only consider 2009 and 2010, let's say, I used the following Linq code.

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()

Questions

  1. Would it have been best if I had used .Take(2) along with a supplemental where condition on the dr.Year?
  2. Are there any better alternatives?
  3. Is my approach worth considerations?


Actually #1 may produce a different result than your current code. For instance if the order was random (I don't see any sorting anywhere) the current code may return any number of results (e.g. no results if the first element doesn't match either condition, even if subsequent ones do)

It sounds like approach #1 would be more correct (unless you actually want the behavior of TakeWhile) You're saying you want the first 2 results that match the given condition, whether or not they are the first ones of the initial list.

For example

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);
} 

Prints:

TakeWhile
2

WhereTake2
21


I would have included the clause in your TakeWhile call in the where clause of the query, is there a reason why you didn't do that? In the long run there probably isn't that much of a difference between the two but the TakeWhile seems unnecessary and makes your code more confusing, IMO.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜