In QGIS 3.18, I have a vector layer of 1000+ features with 100+ attributes, many of which are strings of concatenated elements (substrings) delimited by commas. Some of those elements need to be replaced by other elements – entire elements as delimited, not parts of elements.
What I have done in the past to get the job done is to use replace()
expressions with 20+ clauses in them. Besides being long and unwieldy, this method was extremely impractical due to the fact that some of the elements are contained as substrings within other elements: for example, one element might be '51.1'
, another might be '51.11'
or '51.111'
, but these need to be treated and replaced differently. With the replace
method, this got very messy very fast and required a lot of cleanup work.
I am looking to do this with an array
function, which recognizes delimited elements. I have tried several attempts, such as: array_to_string(regexp_replace(string_to_array("Field_A",','),'51.1','String1'))
which the Field Calculator recognizes as a valid expression but which returns no results, and
array_to_string(
array_foreach(
string_to_array("Field_A",','),
regexp_replace(@element,'51.1','String1')
)
)
which returns results but seems not to be identifying the delimited elements, as I have the same problem as with replace
. Example: 51.11
is replaced as String11
.
I need to be able to list many substring replacements in one expression, if possible.
As an example of the sort of thing I want to do, see the last line of the table below:
Note: I cannot use array_replace
as I am unable to upgrade to QGIS 3.20 on this device at the moment, and this function is unavailable on 3.18.
Best Answer
You can achieve this combining arrays with maps (
key:value
pairs, see help Maps Functions) and the following expression, where in line 4 you list the elements you want to replace, using the pattern'value_old','value_new'
.Explanation: The expression creates an array of all inputs in
fieldA
(line 6) and for each element (line 5) looks in the map (the one from line 4, created as a variable@map
: line 2/3) at what position a key with this values from the array occurs in the map and returns the corresponding value (function map_get, line 7):