Запутался в том, как реализовать методы расширения в LINQ to Objects

Довольно новичок в LINQ и пытаюсь понять методы расширения. Что я пытаюсь сделать:

1) Иметь таблицу с тремя столбцами: col1 (строка), col2 (двойной), col3 (DateTime)

        table1.Rows.Add("string 1", 1, new DateTime(2009, 01, 01));
        table1.Rows.Add("string 1", 2, new DateTime(2009, 02, 01));
        table1.Rows.Add("string 1",3, new DateTime(2009, 03, 01));
        table1.Rows.Add("string 1", 4, new DateTime(2009, 04, 01));
        table1.Rows.Add("string 2",1, new DateTime(2009, 05, 01));
        table1.Rows.Add("string 2", 1, new DateTime(2009, 06, 01));
        table1.Rows.Add("string 2", 5, new DateTime(2009, 07, 01));
        table1.Rows.Add("string 3", 6, new DateTime(2009, 08, 01));

2) Мне нужно написать запрос LINQ для группировки по столбцу 1 и отправить сгруппированные строки методу, который возвращает значение double. Что-то вроде этого

var query = from t in table1
            group t by t.col1 into g
            select new { r1 = g.Key, r2=mycalc(g))

3) и иметь функцию расширения:

public static double Median(this IEnumerable<DataSet1.DataTable1Row> source)
{
  //calc using the grouped row data and return a dobule
}

Я немного работал над этим и не совсем понял. Может кто-нибудь помочь?


person Community    schedule 22.09.2009    source источник


Ответы (1)


Ну, не совсем ясно, какой бит вызывает проблему. Если вы уже использовали метод Median, вы можете изменить query на:

var query = from t in table1
            group t by t.col1 into g
            select new { r1 = g.Key, r2=g.Median() };

Бит Median вызывает у вас проблемы? Вероятно, будет проще сделать что-то вроде:

public static double Median(this IEnumerable<DataSet1.DataTable1Row> source)
{
    List<double> values = source.Select(x => x.col2).ToList();
    values.Sort();
    if ((values.Count % 2) == 1) // Odd number of values
    {
        return values[values.Count/2];
    }
    else // Even number of values: find mean of middle two
    {
        return (values[values.Count/2] + values[values.Count/2 + 1]) / 2;
    }
}

Возможно, есть более эффективные способы сделать это, но я их не знаю...

person Jon Skeet    schedule 22.09.2009