summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Perehonchuk <romanp@meta.com>2024-10-01 06:01:42 -0700
committerFacebook GitHub Bot <facebook-github-bot@users.noreply.github.com>2024-10-01 06:01:42 -0700
commit059ea4d337ec059d7f4909ec0c449f5786e82f5f (patch)
tree3ab3ba3fd4c7eb3ba1ef2792b6be30c7b78a8ff0
parentd83b304490b22c14ad869206eb060287bbb16c82 (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.rs60
-rw-r--r--starlark/testcases/eval/go/set.star6
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]))