К .Take () или нет .Take (), вот в чем вопрос - PullRequest
5 голосов
/ 25 марта 2011

У меня есть коллекция, которая представляет население (M, F) для каждого возраста.

Чтобы прогнозировать численность населения во времени, я должен сначала сделать расчеты с женщинами, чтобы я мог рассчитать процент новорожденных мужчин и женщин на основе статистической константы мужского родов.

Тем не менее, у меня есть первая матрица, которая включает в себя как мужчин, так и женщин по годам.

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

Теперь, чтобы сначала спроецировать женское население, я использую следующее:

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

И я должен учитывать коэффициенты смертности как для текущего (начальный год (2009)), так и для года, на который я хочу прогнозировать, исходя из которого у меня уже есть коэффициенты смертности на каждый год.

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

Это загружает ставки deather с 2009 и позже для каждого года возраста. Следовательно, чтобы рассмотреть только 2009 и 2010, скажем, я использовал следующий код 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()

Вопросы

  1. Было бы лучше, если бы я использовал .Take(2) вместе с дополнительным условием where для dr.Year?
  2. Есть ли лучшие альтернативы?
  3. Стоит ли учитывать мой подход?

Ответы [ 2 ]

1 голос
/ 25 марта 2011

На самом деле # 1 может дать результат, отличный от вашего текущего кода.Например, если порядок был случайным (я не вижу никакой сортировки), текущий код может вернуть любое количество результатов (например, никаких результатов, если первый элемент не соответствует ни одному из условий, даже если последующие соответствуют)

Похоже, что подход № 1 был бы более правильным (если вы на самом деле не хотите поведения TakeWhile)начальный список.

Например

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

Отпечатки:

TakeWhile
2

WhereTake2
21
1 голос
/ 25 марта 2011

Я бы включил предложение в ваш вызов TakeWhile в предложение where запроса, есть ли причина, по которой вы этого не сделали?В долгосрочной перспективе разница между ними, вероятно, не так уж и велика, но TakeWhile кажется ненужным и делает ваш код более запутанным, ИМО.

...