2010-01-15 3 views
0

У меня есть двойной массив [], содержащий множество чисел.Получить среднее значение из double [] между двумя индексами

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

Теперь я хочу, чтобы вычислить среднее значение всех этих значений в моем разделе.

Итак, скажите, что мой раздел от индекса 20 до 40. Теперь у меня есть 20 значений. Есть ли простой способ сделать это на C# или мне нужно перебрать мой массив и рассчитать среднее значение вручную?

ответ

8
var values = new[] { 1, 2, 3, 4, 5, 6, 7, 8 }; 
var average = values.Skip(2).Take(5).Average(); 
+0

Ударьте меня в это ... +1 за то, что сделали это по индексу, как он попросил, а не по фильтрации! – Aaronaught

+0

@Aaronaught: «У меня есть алгоритм, который выбирает разделы из этого массива, которые попадают под определенные условия (значение больше, чем x, значения по меньшей мере y и т. Д.)». То есть выбор по индексу не является единственной проблемой, которую он пытается решить. – jason

+0

+1, действительно круто. – Benny

1

Использование Linq:

var myList = new double[] {1,2,3} 
var avg = myList.Where(i => i > 1 && i < 2).Avg(); 
+0

Это не будет компилировать. – jason

+0

. Где (i => i> 1 && i < 2) --> исправьте меня, если я ошибаюсь, но разве этот предикат не ограничивает значения массива 1 и 2? Если это так, это неправильный ответ, потому что пользователь хочет ограничить индекс массива 1 и 2, поэтому вам нужно получить числа 2 и 3 из массива. –

+0

Я понял, что знает индекс из-за предиката - второе предложение. Итак: почему бы не включить предикат. – Arthur

0

Enumerable.Average Использование:

double[] values = new[] { 1.0, 2.0, 3.14, 2.71, 9.1 }; 
double average = values.Where(x => x > 2.0 && x < 4.0).Average(); 

Поэтому, чтобы использовать это с методами отбора вы должны рассмотреть эти методы возвращают IEnumerable<double>. Так, в качестве примера:

public IEnumerable<double> GreaterThan(double[] values, double value) { 
    for(int i = 0; i < values.Length; i++) { 
     if(values[i] > value) { 
      yield return values[i]; 
    } 
} 

Тогда:

// values is double[] 
double average = GreaterThan(values, 2.0).Average(); 

Вы можете даже сделать выше метод расширения, так что он читает красиво:

double average = values.GreaterThan(2.0).Average(); 

Я хотел бы призвать вас, чтобы написать ваши методы фильтрации возвращаются IEnumerable<double>.

+0

Вы не выбираете по индексу, а по значению. –

+0

@Oliver Hanappi: «У меня есть алгоритм, который выбирает разделы из этого массива, которые попадают под определенные условия (значение больше, чем x, значения по крайней мере y и т. Д.). хочет получить больше, чем просто выбрать по индексу. Вышеприведенное является просто примером. Дело в том, что его методы возвращают 'IEnumerable ', а затем просто позволяют LINQ делать все остальное. – jason

+0

Это также выглядит предварительно tty круто. Таким образом, функция GreaterThan уже возвращает сегмент моего массива, правильно? Но что, если в этом массиве может быть n сегментов? Скажите от индекса 10 до 20, а затем от индекса 50 до 80? –

0

Вы можете использовать пропуск и принимать методы LINQ для выбора конкретных индексов:

var myData = new double[] { ..... }; 
var average = myList.Skip(20).Take(21).Average(); 
+0

Используя Take (20), вы получаете только цифры с индексом от 20 до 39. – Guffa

+0

Хорошая точка, спасибо. –

0
double avg = array 
    .Skip(startIndex) 
    .Take(endIndex - startIndex + 1) 
    .Average(); 
1

Обратите внимание, что если у вас есть номера с индексом 20 до 40, у вас нет 20 номеров, у вас есть 21 номер.

Вы можете использовать метод Range, чтобы создать IEnumerable для индексов, то вы можете использовать средний метод, чтобы получить среднее значение из чисел:

double average = Enumerable.Range(20, 21).Select(i => numbers[i]).Average();