Skip to content

Commit

Permalink
[FEATURE] array_slice expression function
Browse files Browse the repository at this point in the history
  • Loading branch information
andreasneumann committed Aug 6, 2017
1 parent 5bd2e88 commit 8978469
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
51 changes: 51 additions & 0 deletions resources/function_help/json/array_slice
@@ -0,0 +1,51 @@
{
"name": "array_get",
"type": "function",
"description": "Returns a portion of the array. The slice is defined by the startPos and endPos arguments. A slice that ",
"arguments": [{
"arg": "array",
"description": "an array"
},
{
"arg": "startPos",
"description": "the index of the start position of the slice (0 based). The startPos index is included in the slice. If you use a negative startPos, the index is counted from the end of the list (-1 based)."
},
{
"arg": "endPos",
"description": "the index of the start position of the slice (0 based). The endPos index is included in the slice. If you use a negative endPos, the index is counted from the end of the list (-1 based)."
}
],
"examples": [{
"expression": "array_slice(array(1,2,3,4,5),0,3)",
"returns": "array: 1,2,3,4"
},
{
"expression": "array_slice(array(1,2,3,4,5),0,-1)",
"returns": "array: 1,2,3,4,5"
},
{
"expression": "array_slice(array(1,2,3,4,5),-5,-1)",
"returns": "array: 1,2,3,4,5"
},
{
"expression": "array_slice(array(1,2,3,4,5),0,0)",
"returns": "array: 1"
},
{
"expression": "array_slice(array(1,2,3,4,5),-2,-1)",
"returns": "array: 4,5"
},
{
"expression": "array_slice(array(1,2,3,4,5),-1,-1)",
"returns": "array: 5"
},
{
"expression": "array_slice(array('Dufour','Valmiera','Chugiak','Brighton'),1,2)",
"returns": "array: 'Valmiera','Chugiak'"
},
{
"expression": "array_slice(array_slice(array('Dufour','Valmiera','Chugiak','Brighton'),-2,-1)",
"returns": "array: 'Chugiak','Brighton'"
}
]
}
25 changes: 25 additions & 0 deletions src/core/expression/qgsexpressionfunction.cpp
Expand Up @@ -3602,6 +3602,30 @@ static QVariant fcnArrayCat( const QVariantList &values, const QgsExpressionCont
return convertToSameType( list, values.at( 0 ).type() );
}

static QVariant fcnArraySlice( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent )
{
QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
qlonglong startPos = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
const qlonglong endPos = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
qlonglong sliceLength = 0;
// negative positions means positions taken relative to the end of the array
if( startPos < 0 ) {
startPos = list.length() + startPos;
}
if( endPos >= 0 ) {
sliceLength = endPos - startPos + 1;
}
else {
sliceLength = list.length() + endPos - startPos + 1;
}
//avoid negative lengths in QList.mid function
if (sliceLength < 0) {
sliceLength = 0;
}
list = list.mid(startPos,sliceLength);
return list;
}

static QVariant fcnArrayReverse( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent )
{
QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
Expand Down Expand Up @@ -4263,6 +4287,7 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
<< new QgsStaticExpressionFunction( QStringLiteral( "array_remove_at" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "pos" ) ), fcnArrayRemoveAt, QStringLiteral( "Arrays" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "array_remove_all" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "value" ) ), fcnArrayRemoveAll, QStringLiteral( "Arrays" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "array_cat" ), -1, fcnArrayCat, QStringLiteral( "Arrays" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "array_slice" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "startPos" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "endPos" ) ), fcnArraySlice, QStringLiteral( "Arrays" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "array_reverse" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ), fcnArrayReverse, QStringLiteral( "Arrays" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "array_intersect" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array1" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "array2" ) ), fcnArrayIntersect, QStringLiteral( "Arrays" ) )
<< new QgsStaticExpressionFunction( QStringLiteral( "array_distinct" ), 1, fcnArrayDistinct, QStringLiteral( "Arrays" ) )
Expand Down
10 changes: 10 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Expand Up @@ -2422,6 +2422,9 @@ class TestQgsExpression: public QObject
QCOMPARE( QgsExpression( "array_intersect(array('1', '2', '3', '4'), array('0', '5'))" ).evaluate( &context ), QVariant( false ) );

QCOMPARE( QgsExpression( "array_reverse(array('Dufour','Valmiera','Chugiak','Wien','Pisa','Lyon','Essen','Nødebo','Las Palmas')) = array('Las Palmas','Nødebo','Essen','Lyon','Pisa','Wien','Chugiak','Valmiera','Dufour')" ).evaluate( &context ), QVariant( true ) );

QCOMPARE( QgsExpression( "array_slice(array('Dufour','Valmiera','Chugiak','Brighton'),1,2) = array('Valmiera','Chugiak')" ).evaluate( &context ), QVariant( true ) );
QCOMPARE( QgsExpression( "array_slice(array('Dufour','Valmiera','Chugiak','Brighton'),-2,-1) = array('Chugiak','Brighton')" ).evaluate( &context ), QVariant( true ) );
}

void eval_int_array()
Expand Down Expand Up @@ -2486,6 +2489,13 @@ class TestQgsExpression: public QObject

QCOMPARE( QgsExpression( "array_reverse(array(2,4,0,10)) = array(10,0,4,2)" ).evaluate( &context ), QVariant( true ) );

QCOMPARE( QgsExpression( "array_slice(array(1,2,3,4,5),0,3) = array(1,2,3,4)" ).evaluate( &context ), QVariant( true ) );
QCOMPARE( QgsExpression( "array_slice(array(1,2,3,4,5),0,-1) = array(1,2,3,4,5)" ).evaluate( &context ), QVariant( true ) );
QCOMPARE( QgsExpression( "array_slice(array(1,2,3,4,5),-5,-1) = array(1,2,3,4,5)" ).evaluate( &context ), QVariant( true ) );
QCOMPARE( QgsExpression( "array_slice(array(1,2,3,4,5),0,0) = array(1)" ).evaluate( &context ), QVariant( true ) );
QCOMPARE( QgsExpression( "array_slice(array(1,2,3,4,5),-2,-1) = array(4,5)" ).evaluate( &context ), QVariant( true ) );
QCOMPARE( QgsExpression( "array_slice(array(1,2,3,4,5),-1,-1) = array(5)" ).evaluate( &context ), QVariant( true ) );

QgsExpression badArray( QStringLiteral( "array_get('not an array', 0)" ) );
QCOMPARE( badArray.evaluate( &context ), QVariant() );
QVERIFY( badArray.hasEvalError() );
Expand Down

0 comments on commit 8978469

Please sign in to comment.