diff options
author | Roman Perehonchuk <romanp@meta.com> | 2024-10-01 06:01:42 -0700 |
---|---|---|
committer | Facebook GitHub Bot <facebook-github-bot@users.noreply.github.com> | 2024-10-01 06:01:42 -0700 |
commit | 059ea4d337ec059d7f4909ec0c449f5786e82f5f (patch) | |
tree | 3ab3ba3fd4c7eb3ba1ef2792b6be30c7b78a8ff0 | |
parent | d83b304490b22c14ad869206eb060287bbb16c82 (diff) |
issubset
Summary: set([1,2]).issubset([1,2,3]) == True
Reviewed By: stepancheg
Differential Revision: D60527929
fbshipit-source-id: 8dab651fc0a5e5c899d973da08deb00b8a488828
-rw-r--r-- | starlark/src/values/types/set/methods.rs | 60 | ||||
-rw-r--r-- | starlark/testcases/eval/go/set.star | 6 |
2 files changed, 63 insertions, 3 deletions
diff --git a/starlark/src/values/types/set/methods.rs b/starlark/src/values/types/set/methods.rs index ab6ade0e..3d4ea9e2 100644 --- a/starlark/src/values/types/set/methods.rs +++ b/starlark/src/values/types/set/methods.rs @@ -325,7 +325,41 @@ pub(crate) fn set_methods(builder: &mut MethodsBuilder) { } Ok(true) } + + /// Test whether every element in the set is in other iterable. + /// ``` + /// # starlark::assert::is_true(r#" + /// x = set([1, 2, 3]) + /// y = [3, 1, 2] + /// x.issubset(y) + /// # "#); + /// ``` + fn issubset<'v>( + this: SetRef<'v>, + #[starlark(require=pos)] other: ValueOfUnchecked<'v, StarlarkIter<Value<'v>>>, + heap: &'v Heap, + ) -> starlark::Result<bool> { + let other = other.get().iterate(heap)?; + if this.content.is_empty() { + return Ok(true); + } + //TODO(romanp): check if other is already a set + let mut rhs: SmallSet<Value<'v>> = SmallSet::default(); + for elem in other { + rhs.insert_hashed(elem.get_hashed()?); + } + if rhs.is_empty() { + return Ok(false); + } + for elem in this.content.iter_hashed() { + if !rhs.contains_hashed(elem) { + return Ok(false); + } + } + Ok(true) + } } + #[cfg(test)] mod tests { use crate::assert; @@ -551,4 +585,30 @@ mod tests { fn test_is_superset_iter() { assert::is_true("set([1, 2, 3]).issuperset([3, 1])") } + + #[test] + fn test_is_subset() { + assert::is_true("set([1, 2]).issubset(set([1, 3, 2]))") + } + + #[test] + fn test_is_not_subset() { + assert::is_false("set([1, 2]).issubset(set([1, 3, 5]))") + } + + #[test] + fn test_is_subset_empty_lhs() { + assert::is_true("set([]).issubset(set([1, 3, 5]))"); + assert::is_true("set([]).issubset(set([]))") + } + + #[test] + fn test_is_not_subset_empty_rhs() { + assert::is_false("set([1, 2]).issubset(set([]))") + } + + #[test] + fn test_is_subset_iter() { + assert::is_true("set([1, 2]).issubset([1, 3, 2])") + } } diff --git a/starlark/testcases/eval/go/set.star b/starlark/testcases/eval/go/set.star index d1001501..1dbe09de 100644 --- a/starlark/testcases/eval/go/set.star +++ b/starlark/testcases/eval/go/set.star @@ -187,9 +187,9 @@ asserts.true(not set([1,2,3]).issuperset(set([1,2,4]))) # asserts.true(set([1, 2, 3]) > set([1, 2])) # asserts.true(not set([1,2, 3]) > set([1, 2, 3])) -# # issubset: set <= set or set.issubset(iterable) -# asserts.true(set([1,2]).issubset([1,2,3])) -# asserts.true(not set([1,2,3]).issubset(set([1,2,4]))) +# issubset: set <= set or set.issubset(iterable) +asserts.true(set([1,2]).issubset([1,2,3])) +asserts.true(not set([1,2,3]).issubset(set([1,2,4]))) # asserts.true(set([1,2,3]) <= set([1,2,3])) # asserts.true(set([1,2]) <= set([1,2,3])) # asserts.true(not set([1,2,3]) <= set([1,2,4])) |