QGIS – Replacing Strings in Multiple Array Elements by Commas

arrayattribute-tableexpressionqgisreplace

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:

example

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):

array_to_string (
    with_variable(
        'map',
        map('51.1','String1','51.11','String2','51.111','String3','51.13','String4','51.15','String5'),
        array_foreach (
            string_to_array (fieldA),
            map_get (@map,@element)
        )
    )
)

enter image description here