Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New unique() method on list #13195

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/markdown/snippets/array_unique.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
## New `unique()` method on list

List now have a `unique()` method that return a copy of the list without
duplicated elements.

If other lists are provided as arguments to the method, it returns the union
of all lists, without duplicated elements.

```
[1, 1, 2, 2, 3, 3].unique() == [1, 2, 3]
[].unique([1, 2], [2, 3], [3, 4]) == [1, 2, 3, 4]
```
11 changes: 11 additions & 0 deletions docs/yaml/elementary/list.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,14 @@ methods:
- name: length
returns: int
description: Returns the current size of the array / list.

- name: unique
returns: list
description: |
Returns a list without duplicated elements. If other lists are provided
as arguments, it combines those lists and remove duplicated elements.
List order is preserved.
varargs:
name: other
type: list
description: Other lists to merge.
11 changes: 11 additions & 0 deletions mesonbuild/interpreter/primitives/array.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Copyright 2021 The Meson development team
from __future__ import annotations

import itertools
import typing as T

from ...interpreterbase import (
Expand Down Expand Up @@ -33,6 +34,7 @@ def __init__(self, obj: T.List[TYPE_var], interpreter: 'Interpreter') -> None:
'contains': self.contains_method,
'length': self.length_method,
'get': self.get_method,
'unique': self.unique_method,
})

self.trivial_operators.update({
Expand Down Expand Up @@ -91,6 +93,15 @@ def get_method(self, args: T.Tuple[int, T.Optional[TYPE_var]], kwargs: TYPE_kwar
return args[1]
return self.held_object[index]

@FeatureNew('array.unique', '1.5.0')
@noArgsFlattening
@typed_pos_args('array.unique', varargs=list)
@noKwargs
def unique_method(self, args: T.Tuple[T.List[list]], kwargs: TYPE_kwargs) -> list:
# Use dict instead of set to ensure we preserve items order,
# since dict are insertion-ordered since Python 3.7
return list(dict.fromkeys(itertools.chain(self.held_object, *args[0])))

@typed_operator(MesonOperator.PLUS, object)
def op_plus(self, other: TYPE_var) -> T.List[TYPE_var]:
if not isinstance(other, list):
Expand Down
69 changes: 69 additions & 0 deletions test cases/common/17 array/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,72 @@ arr = [

exe = executable('prog', sources : arr)
test('arr test', exe)


# Array arithmetic

array1 = ['foo', 'bar']
array2 = ['qux', 'baz']

if array1 + array2 != ['foo', 'bar', 'qux', 'baz']
error('Array concatenation is broken')
endif
if array2 + array1 != ['qux', 'baz', 'foo', 'bar']
error('Array concatenation is broken')
endif

if array1 + array1 + array1 != ['foo', 'bar', 'foo', 'bar', 'foo', 'bar']
error('Many-array concatenation is broken')
endif


# Array methods

empty = []
one = ['abc']
two = ['def', 'ghi']
combined = [empty, one, two]

file_list = files('a.txt', 'b.txt')
file_a = files('a.txt')
file_c = files('c.txt')

if file_a[0] != file_list[0]
error('Files are not equal')
endif

if not file_list.contains(file_a[0])
error('Contains with ObjectHolder lists does not work')
endif

if file_list.contains(file_c[0])
error('Contains with ObjectHolder lists found nonexistent object')
endif

if empty.contains('abc')
error('Empty is not empty.')
endif

if one.contains('a')
error('One claims to contain a')
endif

if not one.contains('abc')
error('One claims to not contain abc.')
endif

if one.contains('abcd')
error('One claims to contain abcd.')
endif

if file_list.unique(file_a) != file_list
error('File not deduplicated in list')
endif

if empty.unique(one, two) != one + two
error('Unique does not combine arrays')
endif

if [0, 0, 0, 1, 1, 2, 3, 2, 1, 4, 0, 5].unique() != [0, 1, 2, 3, 4, 5]
error('Unique without arguments did not deduplicated integers')
endif
70 changes: 0 additions & 70 deletions test cases/common/56 array methods/meson.build

This file was deleted.

15 changes: 0 additions & 15 deletions test cases/common/63 array arithmetic/meson.build

This file was deleted.

Loading