Skip to content

Commit d06201d

Browse files
committed
interpreter: Add a flatten() method to arrays
This allows users to do two things, flatten potentially nested arrays themselves, and, to safely convert types that may be an array to not an array. ```meson x = [meson.get_external_property('may_be_array)].flatten() ``` ```meson x = ['a', ['b', 'c']] assert(x.flatten() == ['a', 'b', 'c']) ```
1 parent 36de1c6 commit d06201d

File tree

4 files changed

+32
-1
lines changed

4 files changed

+32
-1
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## Array `.flatten()` method
2+
3+
Arrays now have a `.flatten()` method, which turns nested arrays into a single
4+
flat array. This provides the same effect that Meson often does to arrays
5+
internally, such as when passed to most function arguments.

docs/yaml/elementary/list.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,8 @@ methods:
4040
- name: length
4141
returns: int
4242
description: Returns the current size of the array / list.
43+
44+
- name: flatten
45+
returns: array[any]
46+
since: 1.9.0
47+
description: Returns a flattened copy of the array, with all nested arrays removed.

mesonbuild/interpreter/primitives/array.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def __init__(self, obj: T.List[TYPE_var], interpreter: 'Interpreter') -> None:
3333
'contains': self.contains_method,
3434
'length': self.length_method,
3535
'get': self.get_method,
36+
'flatten': self.flatten_method,
3637
})
3738

3839
self.trivial_operators.update({
@@ -106,3 +107,16 @@ def op_index(self, other: int) -> TYPE_var:
106107
return self.held_object[other]
107108
except IndexError:
108109
raise InvalidArguments(f'Index {other} out of bounds of array of size {len(self.held_object)}.')
110+
111+
@noPosargs
112+
@noKwargs
113+
@FeatureNew('array.flatten', '1.9.0')
114+
def flatten_method(self, args: T.List[TYPE_var], kwargs: TYPE_kwargs) -> TYPE_var:
115+
def flatten(obj: TYPE_var) -> T.Iterable[TYPE_var]:
116+
if isinstance(obj, list):
117+
for o in obj:
118+
yield from flatten(o)
119+
else:
120+
yield obj
121+
122+
return list(flatten(self.held_object))

test cases/common/56 array methods/meson.build

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
project('array methods')
1+
project('array methods', meson_version : '>= 1.9')
22

33
empty = []
44
one = ['abc']
@@ -68,3 +68,10 @@ endif
6868
if not combined.contains('ghi')
6969
error('Combined claims not to contain ghi.')
7070
endif
71+
72+
# test array flattening
73+
x = ['a', ['b'], [[[[[[['c'], 'd']]], 'e']]]]
74+
assert(x.length() == 3)
75+
assert(x.flatten().length() == 5)
76+
assert(x.flatten() == ['a', 'b', 'c', 'd', 'e'])
77+
assert(['a', ['b', 'c']].flatten() == ['a', 'b', 'c'])

0 commit comments

Comments
 (0)