diff --git a/docs/markdown/snippets/array-flatten.md b/docs/markdown/snippets/array-flatten.md new file mode 100644 index 000000000000..eaab19c5b2be --- /dev/null +++ b/docs/markdown/snippets/array-flatten.md @@ -0,0 +1,5 @@ +## Array `.flatten()` method + +Arrays now have a `.flatten()` method, which turns nested arrays into a single +flat array. This provides the same effect that Meson often does to arrays +internally, such as when passed to most function arguments. diff --git a/docs/yaml/elementary/list.yml b/docs/yaml/elementary/list.yml index 1ffb6d2d30a3..ddf259c2d4be 100644 --- a/docs/yaml/elementary/list.yml +++ b/docs/yaml/elementary/list.yml @@ -40,3 +40,8 @@ methods: - name: length returns: int description: Returns the current size of the array / list. + +- name: flatten + returns: array[any] + since: 1.9.0 + description: Returns a flattened copy of the array, with all nested arrays removed. diff --git a/mesonbuild/interpreter/primitives/array.py b/mesonbuild/interpreter/primitives/array.py index b42ddeaa4303..5570d6bb2774 100644 --- a/mesonbuild/interpreter/primitives/array.py +++ b/mesonbuild/interpreter/primitives/array.py @@ -33,6 +33,7 @@ def __init__(self, obj: T.List[TYPE_var], interpreter: 'Interpreter') -> None: 'contains': self.contains_method, 'length': self.length_method, 'get': self.get_method, + 'flatten': self.flatten_method, }) self.trivial_operators.update({ @@ -106,3 +107,16 @@ def op_index(self, other: int) -> TYPE_var: return self.held_object[other] except IndexError: raise InvalidArguments(f'Index {other} out of bounds of array of size {len(self.held_object)}.') + + @noPosargs + @noKwargs + @FeatureNew('array.flatten', '1.9.0') + def flatten_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> TYPE_var: + def flatten(obj: TYPE_var) -> T.Iterable[TYPE_var]: + if isinstance(obj, list): + for o in obj: + yield from flatten(o) + else: + yield obj + + return list(flatten(self.held_object)) diff --git a/test cases/common/56 array methods/meson.build b/test cases/common/56 array methods/meson.build index e9e4969c724d..3707775ec27b 100644 --- a/test cases/common/56 array methods/meson.build +++ b/test cases/common/56 array methods/meson.build @@ -1,4 +1,4 @@ -project('array methods') +project('array methods', meson_version : '>= 1.9') empty = [] one = ['abc'] @@ -68,3 +68,10 @@ endif if not combined.contains('ghi') error('Combined claims not to contain ghi.') endif + +# test array flattening +x = ['a', ['b'], [[[[[[['c'], 'd']]], 'e']]]] +assert(x.length() == 3) +assert(x.flatten().length() == 5) +assert(x.flatten() == ['a', 'b', 'c', 'd', 'e']) +assert(['a', ['b', 'c']].flatten() == ['a', 'b', 'c'])