Skip to content

Commit

Permalink
[FEATURE][expression] New array_all() function to check whether
Browse files Browse the repository at this point in the history
an array contains _all_ values of another given array.
  • Loading branch information
nirvn committed Apr 9, 2019
1 parent 9502c35 commit 2582399
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 0 deletions.
9 changes: 9 additions & 0 deletions resources/function_help/json/array_all
@@ -0,0 +1,9 @@
{
"name": "array_all",
"type": "function",
"description": "Returns true if an array contains the all values of a given array.",
"arguments": [ {"arg":"array_a","description":"an array"},
{"arg":"array_b","description":"the array of values to search"}],
"examples": [ { "expression":"array_all(array(1,2,3),array(2,3))", "returns":"true"},
{ "expression":"array_all(array(1,2,3),array(1,2,4))", "returns":"false"}]
}
15 changes: 15 additions & 0 deletions src/core/expression/qgsexpressionfunction.cpp
Expand Up @@ -4495,6 +4495,20 @@ static QVariant fcnArrayContains( const QVariantList &values, const QgsExpressio
return QVariant( QgsExpressionUtils::getListValue( values.at( 0 ), parent ).contains( values.at( 1 ) ) );
}

static QVariant fcnArrayAll( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
{
QVariantList listA = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
QVariantList listB = QgsExpressionUtils::getListValue( values.at( 1 ), parent );
int match = 0;
for ( const auto &item : listB )
{
if ( listA.contains( item ) )
match++;
}

return QVariant( match == listB.count() );
}

static QVariant fcnArrayFind( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
{
return QgsExpressionUtils::getListValue( values.at( 0 ), parent ).indexOf( values.at( 1 ) );
Expand Down Expand Up @@ -5512,6 +5526,7 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
<< new QgsStaticExpressionFunction( QStringLiteral( "array_sort" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "ascending" ), true, true ), fcnArraySort, QStringLiteral( "Arrays" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "array_length" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ), fcnArrayLength, QStringLiteral( "Arrays" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "array_contains" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "value" ) ), fcnArrayContains, QStringLiteral( "Arrays" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "array_all" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array_a" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "array_b" ) ), fcnArrayAll, QStringLiteral( "Arrays" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "array_find" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "value" ) ), fcnArrayFind, QStringLiteral( "Arrays" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "array_get" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "pos" ) ), fcnArrayGet, QStringLiteral( "Arrays" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "array_first" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ), fcnArrayFirst, QStringLiteral( "Arrays" ) )
Expand Down
5 changes: 5 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Expand Up @@ -2784,6 +2784,11 @@ class TestQgsExpression: public QObject

QCOMPARE( QgsExpression( "array_length(\"strings\")" ).evaluate( &context ), QVariant( 2 ) );

QCOMPARE( QgsExpression( "array_all(array(1,2,3), array(2,3))" ).evaluate( &context ), QVariant( true ) );
QCOMPARE( QgsExpression( "array_all(array(1,2,3), array(1,2,3,4))" ).evaluate( &context ), QVariant( false ) );
QCOMPARE( QgsExpression( "array_all(array(1,2,3), 1)" ).evaluate( &context ), QVariant() );
QCOMPARE( QgsExpression( "array_all('string', 123)" ).evaluate( &context ), QVariant() );
QCOMPARE( QgsExpression( "array_all('string', 'invalid')" ).evaluate( &context ), QVariant() );
QCOMPARE( QgsExpression( "array_contains(\"strings\", 'two')" ).evaluate( &context ), QVariant( true ) );
QCOMPARE( QgsExpression( "array_contains(\"strings\", 'three')" ).evaluate( &context ), QVariant( false ) );

Expand Down

0 comments on commit 2582399

Please sign in to comment.