Skip to content

Commit 3c3cc43

Browse files
committed
[FEATURE] Add generate_series(start,stop,step) expression function
The function creates an array containing a sequence of numbers.
1 parent cc5e0e1 commit 3c3cc43

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "generate_series",
3+
"type": "function",
4+
"description": "Creates an array containing a sequence of numbers.",
5+
"arguments": [
6+
{"arg":"start", "description":"first value of the sequence"},
7+
{"arg":"stop", "description":"value that ends the sequence once reached"},
8+
{"arg":"step","optional":true,"default":"1","description":"value used as the increment between values"}
9+
],
10+
"examples": [ { "expression":"generate_series('1,5)", "returns":"array: '1', '2', '3', '4', '5'"},
11+
{ "expression":"generate_series('5,1,-1)", "returns":"array: '5', '4', '3', '2', '1'"}
12+
]
13+
}

src/core/expression/qgsexpressionfunction.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,30 @@ bool QgsExpressionFunction::allParamsStatic( const QgsExpressionNodeFunction *no
220220
return true;
221221
}
222222

223+
static QVariant fcnGenerateSeries( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
224+
{
225+
double start = QgsExpressionUtils::getDoubleValue( values.at( 0 ), parent );
226+
double stop = QgsExpressionUtils::getDoubleValue( values.at( 1 ), parent );
227+
double step = QgsExpressionUtils::getDoubleValue( values.at( 2 ), parent );
228+
229+
if ( step == 0.0 || ( step > 0.0 && start > stop ) || ( step < 0.0 && start < stop ) )
230+
return QVariant();
231+
232+
QVariantList array;
233+
int length = 1;
234+
235+
array << start;
236+
double current = start + step;
237+
while ( ( ( step > 0.0 && current <= stop ) || ( step < 0.0 && current >= stop ) ) && length <= 1000000 )
238+
{
239+
array << current;
240+
current += step;
241+
length++;
242+
}
243+
244+
return array;
245+
}
246+
223247
static QVariant fcnGetVariable( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction * )
224248
{
225249
if ( !context )
@@ -4724,6 +4748,7 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
47244748
<< new QgsStaticExpressionFunction( QStringLiteral( "array_distinct" ), 1, fcnArrayDistinct, QStringLiteral( "Arrays" ) )
47254749
<< new QgsStaticExpressionFunction( QStringLiteral( "array_to_string" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "array" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "delimiter" ), true, "," ) << QgsExpressionFunction::Parameter( QStringLiteral( "emptyvalue" ), true, "" ), fcnArrayToString, QStringLiteral( "Arrays" ) )
47264750
<< new QgsStaticExpressionFunction( QStringLiteral( "string_to_array" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "delimiter" ), true, "," ) << QgsExpressionFunction::Parameter( QStringLiteral( "emptyvalue" ), true, "" ), fcnStringToArray, QStringLiteral( "Arrays" ) )
4751+
<< new QgsStaticExpressionFunction( QStringLiteral( "generate_series" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "start" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "stop" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "step" ), true, 1.0 ), fcnGenerateSeries, QStringLiteral( "Arrays" ) )
47274752

47284753
//functions for maps
47294754
<< new QgsStaticExpressionFunction( QStringLiteral( "map" ), -1, fcnMap, QStringLiteral( "Maps" ) )

tests/src/core/testqgsexpression.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -2607,6 +2607,23 @@ class TestQgsExpression: public QObject
26072607
QCOMPARE( v4, QVariant( "test value" ) );
26082608
}
26092609

2610+
void eval_generate_series()
2611+
{
2612+
QVariantList array;
2613+
array << 1 << 2 << 3 << 4;
2614+
QCOMPARE( QgsExpression( "generate_series(1,4)" ).evaluate(), QVariant( array ) );
2615+
array.clear();
2616+
array << 1 << 1.25 << 1.5 << 1.75 << 2;
2617+
QCOMPARE( QgsExpression( "generate_series(1,2,0.25)" ).evaluate(), QVariant( array ) );
2618+
array.clear();
2619+
array << 10 << 9 << 8;
2620+
QCOMPARE( QgsExpression( "generate_series(10,8,-1)" ).evaluate(), QVariant( array ) );
2621+
2622+
QCOMPARE( QgsExpression( "generate_series(10,11,-1)" ).evaluate(), QVariant() );
2623+
QCOMPARE( QgsExpression( "generate_series(10,5)" ).evaluate(), QVariant() );
2624+
QCOMPARE( QgsExpression( "generate_series(1,2,0)" ).evaluate(), QVariant() );
2625+
}
2626+
26102627
void eval_string_array()
26112628
{
26122629
QgsFeature f( 100 );

0 commit comments

Comments
 (0)