4

Using QGIS expressions, if you have an array, you can get the n-th element by simply adding a number (n) in square brackets (starting with 0 for the first element). Like this, array (1,2,3,4,5,6,7,8)[2] returns 3 (element no. 2/third element).

Is there a way to retrieve more than one element in this way with QGIS expressions?

What I tried, based on similar options in R, but doesn't work here:

array (1,2,3,4,5,6,7,8)[2,3] -- to retrieve elements 2 and 3
array (1,2,3,4,5,6,7,8)[array(2,5)] -- to retrieve elements 2, 3 and 5

3 Answers 3

8

I guess no. At least in Python they are called index brackets and are not meant to contain several indizes. Don't know about other languages like R or C. But you can build a custom function:

from qgis.core import *
from qgis.gui import *

@qgsfunction(args='auto', group='Custom', referenced_columns=[])
# arr is an array-input you want to return several values from by their index
# idxarr is an array-input containing the indizes you want to return from arr
def array_get_several(arr, idxarr, feature, parent):
    elements = [arr[i] for i in idxarr]
    return elements

and use it as array_get_several(array(1,2,3,4,5,6),array(1,2)) which for example returns [2,3]. Note that it returns the values ordered, so e.g. array_get_several(array(1,2,3,4,5,6),array(2,1)) does return [3,2].

2
6

Addendum to @MrXsquared's answer. You can also define a range of indexes.

from qgis.core import *
from qgis.gui import *

@qgsfunction(args='auto', group='Custom', referenced_columns=[])
def array_get_range(arr, start, end, feature, parent):
    return arr[start:end] # exclusive end

array_get_range( array(0,1,2,3,4,5,6,7), 2, 6 ) returns [2, 3, 4, 5].

3
  • @geozelot QGIS already has a function for the second approach. Trying to solve directly in PyQGIS instead of searching if there is a solution in Expression is my bad habit. :DD Commented Nov 3, 2021 at 18:16
  • 1
    Oh that's not the worst habit ,) No need to reinvent the wheel, though.
    – geozelot
    Commented Nov 3, 2021 at 19:23
5

The answer by @MrXsquared is indeed an elegant way to do that, lacking the simple way with just square brackets.

With just native functions, a workaround would be:

array_foreach (
    array(0,3),
    array_get (array(1,2,3,4,5,6), @element)
)

returns: [ 1, 4 ] (position 0 and 3, defined in line 2).

1
  • 3
    ...and the proper way would be to use array_slice. In lower level languages you are referring to the extraction of consecutive array element as slicing the (underlying) array, usually implemented additionally for convenience using bracket slice notation [<start>:<end>].
    – geozelot
    Commented Nov 3, 2021 at 17:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.