Skip to content

Commit 8978469

Browse files
committedAug 6, 2017
[FEATURE] array_slice expression function
1 parent 5bd2e88 commit 8978469

File tree

3 files changed

+86
-0
lines changed

3 files changed

+86
-0
lines changed
 
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"name": "array_get",
3+
"type": "function",
4+
"description": "Returns a portion of the array. The slice is defined by the startPos and endPos arguments. A slice that ",
5+
"arguments": [{
6+
"arg": "array",
7+
"description": "an array"
8+
},
9+
{
10+
"arg": "startPos",
11+
"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)."
12+
},
13+
{
14+
"arg": "endPos",
15+
"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)."
16+
}
17+
],
18+
"examples": [{
19+
"expression": "array_slice(array(1,2,3,4,5),0,3)",
20+
"returns": "array: 1,2,3,4"
21+
},
22+
{
23+
"expression": "array_slice(array(1,2,3,4,5),0,-1)",
24+
"returns": "array: 1,2,3,4,5"
25+
},
26+
{
27+
"expression": "array_slice(array(1,2,3,4,5),-5,-1)",
28+
"returns": "array: 1,2,3,4,5"
29+
},
30+
{
31+
"expression": "array_slice(array(1,2,3,4,5),0,0)",
32+
"returns": "array: 1"
33+
},
34+
{
35+
"expression": "array_slice(array(1,2,3,4,5),-2,-1)",
36+
"returns": "array: 4,5"
37+
},
38+
{
39+
"expression": "array_slice(array(1,2,3,4,5),-1,-1)",
40+
"returns": "array: 5"
41+
},
42+
{
43+
"expression": "array_slice(array('Dufour','Valmiera','Chugiak','Brighton'),1,2)",
44+
"returns": "array: 'Valmiera','Chugiak'"
45+
},
46+
{
47+
"expression": "array_slice(array_slice(array('Dufour','Valmiera','Chugiak','Brighton'),-2,-1)",
48+
"returns": "array: 'Chugiak','Brighton'"
49+
}
50+
]
51+
}

‎src/core/expression/qgsexpressionfunction.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3602,6 +3602,30 @@ static QVariant fcnArrayCat( const QVariantList &values, const QgsExpressionCont
36023602
return convertToSameType( list, values.at( 0 ).type() );
36033603
}
36043604

3605+
static QVariant fcnArraySlice( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent )
3606+
{
3607+
QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
3608+
qlonglong startPos = QgsExpressionUtils::getIntValue( values.at( 1 ), parent );
3609+
const qlonglong endPos = QgsExpressionUtils::getIntValue( values.at( 2 ), parent );
3610+
qlonglong sliceLength = 0;
3611+
// negative positions means positions taken relative to the end of the array
3612+
if( startPos < 0 ) {
3613+
startPos = list.length() + startPos;
3614+
}
3615+
if( endPos >= 0 ) {
3616+
sliceLength = endPos - startPos + 1;
3617+
}
3618+
else {
3619+
sliceLength = list.length() + endPos - startPos + 1;
3620+
}
3621+
//avoid negative lengths in QList.mid function
3622+
if (sliceLength < 0) {
3623+
sliceLength = 0;
3624+
}
3625+
list = list.mid(startPos,sliceLength);
3626+
return list;
3627+
}
3628+
36053629
static QVariant fcnArrayReverse( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent )
36063630
{
36073631
QVariantList list = QgsExpressionUtils::getListValue( values.at( 0 ), parent );
@@ -4263,6 +4287,7 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
42634287
<< new QgsStaticExpressionFunction( QStringLiteral( "array_remove_at" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "pos" ) ), fcnArrayRemoveAt, QStringLiteral( "Arrays" ) )
42644288
<< new QgsStaticExpressionFunction( QStringLiteral( "array_remove_all" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "value" ) ), fcnArrayRemoveAll, QStringLiteral( "Arrays" ) )
42654289
<< new QgsStaticExpressionFunction( QStringLiteral( "array_cat" ), -1, fcnArrayCat, QStringLiteral( "Arrays" ) )
4290+
<< new QgsStaticExpressionFunction( QStringLiteral( "array_slice" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "startPos" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "endPos" ) ), fcnArraySlice, QStringLiteral( "Arrays" ) )
42664291
<< new QgsStaticExpressionFunction( QStringLiteral( "array_reverse" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ), fcnArrayReverse, QStringLiteral( "Arrays" ) )
42674292
<< new QgsStaticExpressionFunction( QStringLiteral( "array_intersect" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array1" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "array2" ) ), fcnArrayIntersect, QStringLiteral( "Arrays" ) )
42684293
<< new QgsStaticExpressionFunction( QStringLiteral( "array_distinct" ), 1, fcnArrayDistinct, QStringLiteral( "Arrays" ) )

‎tests/src/core/testqgsexpression.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2422,6 +2422,9 @@ class TestQgsExpression: public QObject
24222422
QCOMPARE( QgsExpression( "array_intersect(array('1', '2', '3', '4'), array('0', '5'))" ).evaluate( &context ), QVariant( false ) );
24232423

24242424
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 ) );
2425+
2426+
QCOMPARE( QgsExpression( "array_slice(array('Dufour','Valmiera','Chugiak','Brighton'),1,2) = array('Valmiera','Chugiak')" ).evaluate( &context ), QVariant( true ) );
2427+
QCOMPARE( QgsExpression( "array_slice(array('Dufour','Valmiera','Chugiak','Brighton'),-2,-1) = array('Chugiak','Brighton')" ).evaluate( &context ), QVariant( true ) );
24252428
}
24262429

24272430
void eval_int_array()
@@ -2486,6 +2489,13 @@ class TestQgsExpression: public QObject
24862489

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

2492+
QCOMPARE( QgsExpression( "array_slice(array(1,2,3,4,5),0,3) = array(1,2,3,4)" ).evaluate( &context ), QVariant( true ) );
2493+
QCOMPARE( QgsExpression( "array_slice(array(1,2,3,4,5),0,-1) = array(1,2,3,4,5)" ).evaluate( &context ), QVariant( true ) );
2494+
QCOMPARE( QgsExpression( "array_slice(array(1,2,3,4,5),-5,-1) = array(1,2,3,4,5)" ).evaluate( &context ), QVariant( true ) );
2495+
QCOMPARE( QgsExpression( "array_slice(array(1,2,3,4,5),0,0) = array(1)" ).evaluate( &context ), QVariant( true ) );
2496+
QCOMPARE( QgsExpression( "array_slice(array(1,2,3,4,5),-2,-1) = array(4,5)" ).evaluate( &context ), QVariant( true ) );
2497+
QCOMPARE( QgsExpression( "array_slice(array(1,2,3,4,5),-1,-1) = array(5)" ).evaluate( &context ), QVariant( true ) );
2498+
24892499
QgsExpression badArray( QStringLiteral( "array_get('not an array', 0)" ) );
24902500
QCOMPARE( badArray.evaluate( &context ), QVariant() );
24912501
QVERIFY( badArray.hasEvalError() );

0 commit comments

Comments
 (0)
Please sign in to comment.