Linq - вычислите несколько средних чисел в одном запросе

Посмотрите пример здесь.

$("#slider").animate({width:'toggle'});

https://jsfiddle.net/q1pdgn96/2/

5
задан Graham Clark 29 June 2009 в 12:20
поделиться

3 ответа

Более интересным будет вопрос, как сделать это на сервере, например, чтобы следующий запрос был преобразован в LINQ to SQL.

        var q = from single in Enumerable.Range(1, 1)
                let xs = sourceSequence
                select new
                {
                    Aggregate1 = xs.Sum(),
                    Aggregate2 = xs.Average(),
                    // etc
                };

Но нет смысла пытаться его втиснуть в один запрос, если вы используете LINQ to Objects. Просто напишите агрегаты отдельно:

var aggregate1 = xs.Sum();
var aggregate2 = xs.Average();
// etc

Другими словами:

var xs = from a in listOfAs
         from b in a.Bs
         select new { A=a, B=b };

var average1 = xs.Average(x => (x.B.Completed - x.A.Created).TotalSeconds);
var average2 = xs.Average(x => (x.B.Completed - x.B.Created).TotalSeconds);

Правильно ли я понял?

Редактировать: Дэвид Б. ответил аналогичным образом. Я забыл преобразовать TimeSpan в простой числовой тип, поддерживаемый методом Average. Используйте TotalMilliseconds / Seconds / Minutes или любой другой подходящий масштаб.

5
ответ дан 13 December 2019 в 22:14
поделиться

Sql и Linq различаются по некоторым пунктам. Sql имеет неявную группировку - возьмите все это и сделайте одну группу. В linq можно имитировать неявную группировку, введя константу для группировки.

var query = 
  from i in Enumerable.Repeat(0, 1)
  from a in AList
  from b in a.BList
  select new {i, a, b} into x
  group x by x.i into g
  select new
  {
    Avg1 = g.Average(x => (x.b.CompletedDate - x.a.CreatedDate)
       .TotalMilliseconds ),
    Avg2 = g.Average(x => (x.b.CompletedDate - x.b.CreatedDate)
       .TotalMilliseconds )
  };
4
ответ дан 13 December 2019 в 22:14
поделиться

Давайте начнем с получения среднего времени между началом B и finish:

1) Сначала вам нужна разница во времени между началом и концом каждого объекта B, чтобы вы сделали это:

List<TimeSpan> timeSpans = new List<TimeSpan>();
foreach (B myB in BList)
{
  TimeSpan myTimeSpan = myB.CompletedDate.Subtract(myB.CreatedDate);
  timeSpans.Add(myTimeSpan);
}

2) Теперь вам нужно получить среднее значение этого. Вы можете сделать это с помощью лямбда-выражений:

//This will give you the average time it took to complete a task in minutes
Double averageTimeOfB = timeSpans.average(timeSpan => timeSpan.TotalMinutes);

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

1) Получите разницу во времени для даты начала A и каждого из B дата завершения:

 List<TimeSpan> timeSpans_2 = new List<TimeSpan>();
 foreach (B myB in BList)
 {
    TimeSpan myTimeSpan = myB.CompletedDate.Subtract(objectA.CreatedDate);
    timeSpans_2.Add(myTimeSpan);
 }

2) Получите среднее значение этих временных различий точно так же, как указано выше:

//This will give you the average time it took to complete a task in minutes
Double averageTimeOfAandB = timeSpans_2.average(timeSpan => timeSpan.TotalMinutes);

И готово. Я надеюсь, что это помогает. Обратите внимание, что этот код не был протестирован.

РЕДАКТИРОВАТЬ: Помните, что LINQ использует выражения Lamda, но представляет собой скорее синтаксический сахар (мало что знаю о реализации, поэтому я надеюсь, что вы не будете обвинять меня). А также вы можете заключить предоставляемые мной реализации в методы, чтобы вы могли вызывать их несколько раз для списка объектов A.

1
ответ дан 13 December 2019 в 22:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: