Подсчет количества истинных элементов в логическом массиве

В Chapel я могу подсчитать количество элементов массива, равное заданному значению, как

var a = [1,2,5,5,5];
writeln( a.count( 5 ) );  // this gives 3

но аналогичный метод, похоже, не работает для подсчета количества истинных элементов:

writeln( count( a > 1 ) );
writeln( ( a > 1 ).count( true ) );

В этом случае мне нужно написать явный цикл for или есть какая-то другая функция (или метод) для этой цели...?


Обновлять

После еще одного эксперимента кажется, что если я сохраню результат a == 5 в новый массив

var mask = ( a == 5 );

тогда он работает так, как ожидалось

writeln( mask.count( true ) );  // gives 3

Итак, a == 5 может представлять что-то отличное от объекта массива и поэтому не предоставляет .count() напрямую?


person Community    schedule 11.05.2017    source источник
comment
вы считаете: a.count( 5 ) эквивалентным: count( a > 1 ) ???   -  person Nir Alfasi    schedule 12.05.2017
comment
О нет, извините, я попытался сделать более общий подсчет, используя операторы сравнения. Чтобы соответствовать первому примеру, я хочу попробовать count( a == 5 ).   -  person    schedule 12.05.2017
comment
Chapel поддерживает повышение, поэтому выражение a == 5 по существу продвигает оператор ==, что приводит к множеству значений, false false true true true.   -  person Brad    schedule 12.05.2017


Ответы (1)


Проблема, с которой вы столкнулись, заключается в том, что метод .count() определен для массивов, поэтому вызов его для a — это нормально. Однако выражение a > 1 не является массивом, это выражение итератора, а выражения итератора (в настоящее время) не поддерживают метод .count() и не приводят к массивам (см.*).
Таким образом, проблема не имеет что-либо, связанное с подсчетом логических значений.
У вас возникла бы похожая проблема, если бы вы считали другие расширенные выражения в массивах:

var a = [ 1, 2, 5, 5,  5],
    b = [ 2, 4, 6, 8, 10];

writeln( ( a + b ).count( 6 ) );

Два неудовлетворительных способа решить эту проблему:

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

writeln( + reduce ( a > 1 ) );

*) = возможно, что-то из этого следует изменить...

person Brad    schedule 12.05.2017
comment
Я не читал ваш ответ, а просто продолжал экспериментировать (поэтому обновил свой вопрос, прежде чем читать ваш ответ, извините!). Но ладно, теперь я понял... Я также поэкспериментирую с редукционным подходом. Благодарность! - person ; 12.05.2017