From d3e2bd1eae9f6548fd0734026cc169f83c89999d Mon Sep 17 00:00:00 2001 From: uclaros Date: Wed, 16 Dec 2020 20:40:04 +0200 Subject: [PATCH] Added array_sum expression function --- resources/function_help/json/array_sum | 10 ++++++++ src/core/expression/qgsexpressionfunction.cpp | 24 +++++++++++++++++++ tests/src/core/testqgsexpression.cpp | 5 +++- 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 resources/function_help/json/array_sum diff --git a/resources/function_help/json/array_sum b/resources/function_help/json/array_sum new file mode 100644 index 00000000000..aa0a6c9961d --- /dev/null +++ b/resources/function_help/json/array_sum @@ -0,0 +1,10 @@ +{ + "name": "array_sum", + "type": "function", + "groups": ["Arrays"], + "description": "Returns the sum of arithmetic values in an array. Non numeric values in the array are ignored.", + "arguments": [ {"arg":"array","description":"an array"} ], + "examples": [ + { "expression":"array_sum(array(0,1,39.4,1.6,'a'))", "returns":"42.0"} + ] +} diff --git a/src/core/expression/qgsexpressionfunction.cpp b/src/core/expression/qgsexpressionfunction.cpp index fab01d12b1d..990a0e1421c 100644 --- a/src/core/expression/qgsexpressionfunction.cpp +++ b/src/core/expression/qgsexpressionfunction.cpp @@ -5424,6 +5424,29 @@ static QVariant fcnArrayMajority( const QVariantList &values, const QgsExpressio return list.isEmpty() ? QVariant() : hash.keys( maxValue ); } +static QVariant fcnArraySum( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) +{ + const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent ); + int i = 0; + double total = 0.0; + for ( const auto &item : list ) + { + switch ( item.userType() ) + { + case QMetaType::Int: + case QMetaType::UInt: + case QMetaType::LongLong: + case QMetaType::ULongLong: + case QMetaType::Float: + case QMetaType::Double: + total += item.toDouble(); + ++i; + break; + } + } + return i == 0 ? QVariant() : total; +} + static QVariant convertToSameType( const QVariant &value, QVariant::Type type ) { QVariant result = value; @@ -7034,6 +7057,7 @@ const QList &QgsExpression::Functions() << new QgsStaticExpressionFunction( QStringLiteral( "array_mean" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ), fcnArrayMean, QStringLiteral( "Arrays" ) ) << new QgsStaticExpressionFunction( QStringLiteral( "array_median" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ), fcnArrayMedian, QStringLiteral( "Arrays" ) ) << new QgsStaticExpressionFunction( QStringLiteral( "array_majority" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ), fcnArrayMajority, QStringLiteral( "Arrays" ) ) + << new QgsStaticExpressionFunction( QStringLiteral( "array_sum" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ), fcnArraySum, QStringLiteral( "Arrays" ) ) << new QgsStaticExpressionFunction( QStringLiteral( "array_append" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "value" ) ), fcnArrayAppend, QStringLiteral( "Arrays" ) ) << new QgsStaticExpressionFunction( QStringLiteral( "array_prepend" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "value" ) ), fcnArrayPrepend, QStringLiteral( "Arrays" ) ) << new QgsStaticExpressionFunction( QStringLiteral( "array_insert" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "pos" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "value" ) ), fcnArrayInsert, QStringLiteral( "Arrays" ) ) diff --git a/tests/src/core/testqgsexpression.cpp b/tests/src/core/testqgsexpression.cpp index 1d591da8c2a..517b0f0ac44 100644 --- a/tests/src/core/testqgsexpression.cpp +++ b/tests/src/core/testqgsexpression.cpp @@ -1640,7 +1640,7 @@ class TestQgsExpression: public QObject QTest::newRow( "array_last(array('a', 'b', 'c'))" ) << QStringLiteral( "array_last(array('a', 'b', 'c'))" ) << false << QVariant( "c" ); QTest::newRow( "array_last(array())" ) << QStringLiteral( "array_last(array())" ) << false << QVariant(); - // array_min, array_max, array_mean, array_median, array_majority + // array_min, array_max, array_mean, array_median, array_majority, array_sum QTest::newRow( "array_min(array())" ) << QStringLiteral( "array_min(array())" ) << false << QVariant(); QTest::newRow( "array_min(array(-1, 0, 1, 2))" ) << QStringLiteral( "array_min(array(-1, 0, 1, 2))" ) << false << QVariant( -1 ); QTest::newRow( "array_min(array(make_date(2020,12,11),make_date(2020,12,12),make_date(2020,12,13)))" ) << QStringLiteral( "array_min(array(make_date(2020,12,11),make_date(2020,12,12),make_date(2020,12,13)))" ) << false << QVariant( QDate( 2020, 12, 11 ) ); @@ -1655,6 +1655,9 @@ class TestQgsExpression: public QObject QTest::newRow( "array_median(array(0,0,1,2,2,42,'a','b'))" ) << QStringLiteral( "array_median(array(0,0,1,2,2,42,'a','b'))" ) << false << QVariant( 1.5 ); QTest::newRow( "array_majority(array())" ) << QStringLiteral( "array_majority(array())" ) << false << QVariant(); QTest::newRow( "array_majority(array(1,2,42,42,'a','b'))" ) << QStringLiteral( "array_majority(array(1,2,42,42,'a','b'))" ) << false << QVariant( QVariantList() << 42 ); + QTest::newRow( "array_sum(array())" ) << QStringLiteral( "array_mean(array())" ) << false << QVariant(); + QTest::newRow( "array_sum(array('a','b','c'))" ) << QStringLiteral( "array_mean(array('a','b','c'))" ) << false << QVariant(); + QTest::newRow( "array_sum(array(0,1,39.4,1.6,'a'))" ) << QStringLiteral( "array_mean(array(0,1,39.4,1.6,'a'))" ) << false << QVariant( 42.0 ); // file functions QTest::newRow( "base_file_name(5)" ) << QStringLiteral( "base_file_name(5)" ) << false << QVariant( "5" );