From 954335040ee7da88a902283d6bec0aedb8b07e8d Mon Sep 17 00:00:00 2001 From: roya0045 Date: Mon, 9 Nov 2020 15:10:13 -0500 Subject: [PATCH 1/6] Allow negative array get --- resources/function_help/json/array_get | 7 +++++-- src/core/expression/qgsexpressionfunction.cpp | 3 ++- tests/src/core/testqgsexpression.cpp | 4 +++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/resources/function_help/json/array_get b/resources/function_help/json/array_get index f713fd372fa..4962fc88a1f 100644 --- a/resources/function_help/json/array_get +++ b/resources/function_help/json/array_get @@ -1,8 +1,11 @@ { "name": "array_get", "type": "function", - "description": "Returns the Nth value (0 for the first one) of an array.", + "description": "Returns the Nth value (0 for the first one) or the last -Nth value (-1 for the last one) of an array.", "arguments": [ {"arg":"array","description":"an array"}, {"arg":"index","description":"the index to get (0 based)"}], - "examples": [ { "expression":"array_get(array('a','b','c'),1)", "returns":"'b'"}] + "examples": [ + { "expression":"array_get(array('a','b','c'),1)", "returns":"'b'"}, + { "expression":"array_get(array('a','b','c'),-1)", "returns":"'c'"} + ] } diff --git a/src/core/expression/qgsexpressionfunction.cpp b/src/core/expression/qgsexpressionfunction.cpp index a905f6da9e9..0ea1b7d7d5a 100644 --- a/src/core/expression/qgsexpressionfunction.cpp +++ b/src/core/expression/qgsexpressionfunction.cpp @@ -5229,7 +5229,8 @@ static QVariant fcnArrayGet( const QVariantList &values, const QgsExpressionCont { const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent ); const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ); - if ( pos < 0 || pos >= list.length() ) return QVariant(); + if ( pos >= list.length() ) return QVariant(); + if ( pos < 0 && ( list.size() + pos ) >= 0 ) return list.at( list.size() + pos ); return list.at( pos ); } diff --git a/tests/src/core/testqgsexpression.cpp b/tests/src/core/testqgsexpression.cpp index 18f2a02620b..f70821f9b83 100644 --- a/tests/src/core/testqgsexpression.cpp +++ b/tests/src/core/testqgsexpression.cpp @@ -3326,7 +3326,9 @@ class TestQgsExpression: public QObject QCOMPARE( QgsExpression( "array_get(\"ints\", 1)" ).evaluate( &context ), QVariant( -2 ) ); QCOMPARE( QgsExpression( "array_get(\"ints\", 2)" ).evaluate( &context ), QVariant() ); - QCOMPARE( QgsExpression( "array_get(\"ints\", -1)" ).evaluate( &context ), QVariant() ); + QCOMPARE( QgsExpression( "array_get(\"ints\", -1)" ).evaluate( &context ), QVariant( -2 ) ); + QCOMPARE( QgsExpression( "array_get(\"ints\", -2)" ).evaluate( &context ), QVariant( 1 ) ); + QCOMPARE( QgsExpression( "array_get(\"ints\", -3)" ).evaluate( &context ), QVariant() ); QVariantList appendExpected = array; appendExpected << 3; From 892e00e0572be5a98fb03348e9bcc323f45b0472 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 12 Nov 2020 07:45:46 -0500 Subject: [PATCH 2/6] try lenght not size --- src/core/expression/qgsexpressionfunction.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/expression/qgsexpressionfunction.cpp b/src/core/expression/qgsexpressionfunction.cpp index f964aa56ac7..6eba0e9e6d3 100644 --- a/src/core/expression/qgsexpressionfunction.cpp +++ b/src/core/expression/qgsexpressionfunction.cpp @@ -5325,7 +5325,8 @@ static QVariant fcnArrayGet( const QVariantList &values, const QgsExpressionCont const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent ); const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ); if ( pos >= list.length() ) return QVariant(); - if ( pos < 0 && ( list.size() + pos ) >= 0 ) return list.at( list.size() + pos ); + if ( pos < 0 && ( list.length() + pos ) >= 0 ) + return list.at( list.length() + pos ); return list.at( pos ); } From 820f3b9bc7086c9327d7c14011939aa6fb42f064 Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 12 Nov 2020 11:55:52 -0500 Subject: [PATCH 3/6] adapt tests --- tests/src/core/testqgsexpression.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/src/core/testqgsexpression.cpp b/tests/src/core/testqgsexpression.cpp index 0ea2a32a291..53ac4dce3b0 100644 --- a/tests/src/core/testqgsexpression.cpp +++ b/tests/src/core/testqgsexpression.cpp @@ -3333,7 +3333,8 @@ class TestQgsExpression: public QObject QCOMPARE( QgsExpression( "array_get(\"strings\", 1)" ).evaluate( &context ), QVariant( "two" ) ); QCOMPARE( QgsExpression( "array_get(\"strings\", 2)" ).evaluate( &context ), QVariant() ); - QCOMPARE( QgsExpression( "array_get(\"strings\", -1)" ).evaluate( &context ), QVariant() ); + QCOMPARE( QgsExpression( "array_get(\"strings\", -1)" ).evaluate( &context ), QVariant( "two" ) ); + QCOMPARE( QgsExpression( "array_get(\"strings\", -4)" ).evaluate( &context ), QVariant() ); QStringList appendExpected = array; appendExpected << QStringLiteral( "three" ); From 551d56312240dfb9f321a3f253c413321ff0152b Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 13 Nov 2020 18:57:45 -0500 Subject: [PATCH 4/6] safer handling --- src/core/expression/qgsexpressionfunction.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/expression/qgsexpressionfunction.cpp b/src/core/expression/qgsexpressionfunction.cpp index 6eba0e9e6d3..6e958dcd6e3 100644 --- a/src/core/expression/qgsexpressionfunction.cpp +++ b/src/core/expression/qgsexpressionfunction.cpp @@ -5324,10 +5324,10 @@ static QVariant fcnArrayGet( const QVariantList &values, const QgsExpressionCont { const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent ); const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ); - if ( pos >= list.length() ) return QVariant(); - if ( pos < 0 && ( list.length() + pos ) >= 0 ) + if ( pos < list.length() && pos >=0 ) return list.at( pos ); + elif ( pos < 0 && ( list.length() + pos ) >= 0 ) return list.at( list.length() + pos ); - return list.at( pos ); + return QVariant(); } static QVariant fcnArrayFirst( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * ) From 2688389332b3e059554abb87444319e4083405b4 Mon Sep 17 00:00:00 2001 From: Alex Date: Fri, 13 Nov 2020 19:43:11 -0500 Subject: [PATCH 5/6] elif is not a thing in c++ --- src/core/expression/qgsexpressionfunction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/expression/qgsexpressionfunction.cpp b/src/core/expression/qgsexpressionfunction.cpp index 6e958dcd6e3..8a4b0e9e072 100644 --- a/src/core/expression/qgsexpressionfunction.cpp +++ b/src/core/expression/qgsexpressionfunction.cpp @@ -5325,7 +5325,7 @@ static QVariant fcnArrayGet( const QVariantList &values, const QgsExpressionCont const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent ); const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ); if ( pos < list.length() && pos >=0 ) return list.at( pos ); - elif ( pos < 0 && ( list.length() + pos ) >= 0 ) + else if ( pos < 0 && ( list.length() + pos ) >= 0 ) return list.at( list.length() + pos ); return QVariant(); } From a36de0942b6bcc9cbb13bf5eaa76517cc32e83e1 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 14 Nov 2020 10:53:51 -0500 Subject: [PATCH 6/6] layout --- src/core/expression/qgsexpressionfunction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/expression/qgsexpressionfunction.cpp b/src/core/expression/qgsexpressionfunction.cpp index 8a4b0e9e072..9e4d0bd4694 100644 --- a/src/core/expression/qgsexpressionfunction.cpp +++ b/src/core/expression/qgsexpressionfunction.cpp @@ -5324,7 +5324,7 @@ static QVariant fcnArrayGet( const QVariantList &values, const QgsExpressionCont { const QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent ); const int pos = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ); - if ( pos < list.length() && pos >=0 ) return list.at( pos ); + if ( pos < list.length() && pos >= 0 ) return list.at( pos ); else if ( pos < 0 && ( list.length() + pos ) >= 0 ) return list.at( list.length() + pos ); return QVariant();