Skip to content

Commit 7373036

Browse files
committed
[FEATURE] add string_to_array() and array_to_string() functions
1 parent 631db7b commit 7373036

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "array_to_string",
3+
"type": "function",
4+
"description": "Concatenates array elements into a string separated by a delimiter using and optional string for empty values.",
5+
"arguments": [
6+
{"arg":"array", "description":"the input array"},
7+
{"arg":"delimiter","optional":true,"default":"','","description":"the string delimiter used to separate concatenated array elements"},
8+
{"arg":"emptyvalue","optional":true,"default":"''","description":"the optional string to use as replacement to empty values"}],
9+
"examples": [ { "expression":"array_to_string(array('1','2','3'),',')", "returns":"'1,2,3'"},
10+
{ "expression":"array_to_string(array('1','','3'),',','0')", "returns":"'1,0,3'"}
11+
]
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "string_to_array",
3+
"type": "function",
4+
"description": "Splits string into an array using supplied delimiter and optional string for empty values.",
5+
"arguments": [
6+
{"arg":"string", "description":"the input string"},
7+
{"arg":"delimiter","optional":true,"default":"','","description":"the string delimiter used to split the input string"},
8+
{"arg":"emptyvalue","optional":true,"default":"''","description":"the optional string to use as replacement to empty values"}],
9+
"examples": [ { "expression":"string_to_array('1,2,3',',')", "returns":"array: '1', '2', '3'"},
10+
{ "expression":"string_to_array('1,,3',',','0')", "returns":"array: '1', '0', '3'"}
11+
]
12+
}

src/core/qgsexpression.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3335,6 +3335,43 @@ static QVariant fcnArrayIntersect( const QVariantList& values, const QgsExpressi
33353335
return QVariant( false );
33363336
}
33373337

3338+
static QVariant fcnArrayToString( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
3339+
{
3340+
QVariantList array = getListValue( values.at( 0 ), parent );
3341+
QString delimiter = getStringValue( values.at( 1 ), parent );
3342+
QString empty = getStringValue( values.at( 2 ), parent );
3343+
3344+
QString str;
3345+
3346+
for ( QVariantList::const_iterator it = array.constBegin(); it != array.constEnd(); ++it )
3347+
{
3348+
str += ( *it ).toString().isEmpty() == false ? ( *it ).toString() : empty;
3349+
if ( it != ( array.constEnd() - 1 ) )
3350+
{
3351+
str += delimiter;
3352+
}
3353+
}
3354+
3355+
return QVariant( str );
3356+
}
3357+
3358+
static QVariant fcnStringToArray( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
3359+
{
3360+
QString str = getStringValue( values.at( 0 ), parent );
3361+
QString delimiter = getStringValue( values.at( 1 ), parent );
3362+
QString empty = getStringValue( values.at( 2 ), parent );
3363+
3364+
QStringList list = str.split( delimiter );
3365+
QVariantList array;
3366+
3367+
for ( QStringList::const_iterator it = list.constBegin(); it != list.constEnd(); ++it )
3368+
{
3369+
array += ( *it ).isEmpty() == false ? *it : empty;
3370+
}
3371+
3372+
return array;
3373+
}
3374+
33383375
static QVariant fcnMap( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
33393376
{
33403377
QVariantMap result;
@@ -3691,6 +3728,8 @@ const QList<QgsExpression::Function*>& QgsExpression::Functions()
36913728
<< new StaticFunction( QStringLiteral( "array_remove_all" ), ParameterList() << Parameter( QStringLiteral( "array" ) ) << Parameter( QStringLiteral( "value" ) ), fcnArrayRemoveAll, QStringLiteral( "Arrays" ) )
36923729
<< new StaticFunction( QStringLiteral( "array_cat" ), -1, fcnArrayCat, QStringLiteral( "Arrays" ) )
36933730
<< new StaticFunction( QStringLiteral( "array_intersect" ), ParameterList() << Parameter( QStringLiteral( "array1" ) ) << Parameter( QStringLiteral( "array2" ) ), fcnArrayIntersect, QStringLiteral( "Arrays" ) )
3731+
<< new StaticFunction( QStringLiteral( "array_to_string" ), ParameterList() << Parameter( QStringLiteral( "array" ) ) << Parameter( QStringLiteral( "delimiter" ), true, "," ) << Parameter( QStringLiteral( "emptyvalue" ), true, "" ), fcnArrayToString, QStringLiteral( "Arrays" ) )
3732+
<< new StaticFunction( QStringLiteral( "string_to_array" ), ParameterList() << Parameter( QStringLiteral( "string" ) ) << Parameter( QStringLiteral( "delimiter" ), true, "," ) << Parameter( QStringLiteral( "emptyvalue" ), true, "" ), fcnStringToArray, QStringLiteral( "Arrays" ) )
36943733

36953734
//functions for maps
36963735
<< new StaticFunction( QStringLiteral( "map" ), -1, fcnMap, QStringLiteral( "Maps" ) )

tests/src/core/testqgsexpression.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,9 @@ class TestQgsExpression: public QObject
859859
QTest::newRow( "concat" ) << "concat('a', 'b', 'c', 'd')" << false << QVariant( "abcd" );
860860
QTest::newRow( "concat function single" ) << "concat('a')" << false << QVariant( "a" );
861861
QTest::newRow( "concat function with NULL" ) << "concat(NULL,'a','b')" << false << QVariant( "ab" );
862+
QTest::newRow( "array_to_string" ) << "array_to_string(array(1,2,3),',')" << false << QVariant( "1,2,3" );
863+
QTest::newRow( "array_to_string with custom empty value" ) << "array_to_string(array(1,'',3),',','*')" << false << QVariant( "1,*,3" );
864+
QTest::newRow( "array_to_string fail passing non-array" ) << "array_to_string('non-array',',')" << true << QVariant();
862865

863866
//fuzzy matching
864867
QTest::newRow( "levenshtein" ) << "levenshtein('kitten','sitting')" << false << QVariant( 3 );
@@ -2180,8 +2183,10 @@ class TestQgsExpression: public QObject
21802183
QCOMPARE( QgsExpression( "array()" ).evaluate( &context ), QVariant( ) );
21812184
builderExpected << "hello";
21822185
QCOMPARE( QgsExpression( "array('hello')" ).evaluate( &context ), QVariant( builderExpected ) );
2186+
QCOMPARE( QgsExpression( "string_to_array('hello',',')" ).evaluate( &context ), QVariant( builderExpected ) );
21832187
builderExpected << "world";
21842188
QCOMPARE( QgsExpression( "array('hello', 'world')" ).evaluate( &context ), QVariant( builderExpected ) );
2189+
QCOMPARE( QgsExpression( "string_to_array('hello,world',',')" ).evaluate( &context ), QVariant( builderExpected ) );
21852190

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

0 commit comments

Comments
 (0)