Step 5 of 6
Set operations: union, intersection, difference
Sets can be combined the way you did with Venn diagrams at school. Who came on both days? Who came at all? Which required skills is a candidate missing?
use std::collections::BTreeSet;
fn main() {
let monday = BTreeSet::from(["ana", "bo", "cy", "dee"]);
let tuesday = BTreeSet::from(["bo", "dee", "eli"]);
println!("both days: {:?}", &monday & &tuesday);
println!("either day: {:?}", &monday | &tuesday);
println!("only monday: {:?}", &monday - &tuesday);
println!("exactly one day: {:?}", &monday ^ &tuesday);
for name in monday.intersection(&tuesday) {
println!("{name} came twice");
}
println!("{}", tuesday.is_subset(&monday));
}
both days: {"bo", "dee"}
either day: {"ana", "bo", "cy", "dee", "eli"}
only monday: {"ana", "cy"}
exactly one day: {"ana", "cy", "eli"}
bo came twice
dee came twice
false
BTreeSet::from([...])builds a set from an array in one go (HashSet::from,HashMap::from([(k, v), ...])andBTreeMap::fromwork the same way).The operators build a new set from two borrowed ones:
Operator Method Elements in the result &a & &ba.intersection(&b)in both &a | &ba.union(&b)in either &a - &ba.difference(&b)in abut not inb&a ^ &ba.symmetric_difference(&b)in exactly one of them The methods don't build a set; they give you the elements one by one, ready for a
forloop. Each element comes as a reference (&&strhere,&Stringfor a set of Strings): clone it if you need an owned copy.is_subset,is_supersetandis_disjoint(no elements in common) answer yes/no questions.
The same operators and methods work on HashSet. The results are HashSets too, so sort them before printing.
Common mistakes
Forgetting the
&s. The operators take the sets by reference:use std::collections::BTreeSet; fn main() { let a = BTreeSet::from([1, 2]); let b = BTreeSet::from([2, 3]); let c = a & b; println!("{:?}", c); }error[E0369]: no implementation for `BTreeSet<{integer}> & BTreeSet<{integer}>`Write
&a & &b.Mixing up the direction of
-.&a - &bis "a without b";&b - &ais a different set.
Your task
A job board matches candidates to roles. Write fn missing_skills(required: &HashSet<String>, have: &HashSet<String>) -> Vec<String> that returns the required skills the candidate doesn't have, sorted alphabetically.
Challenge 2
Write fn common_friends(a: &[&str], b: &[&str]) -> Vec<String> that returns the names appearing in both friend lists, each once, in alphabetical order. The lists may contain repeats. Build a BTreeSet from each list and use intersection (its results come out sorted).
Challenge 3
Compare the tags of two articles. The input is two lines of space-separated tags. Print the shared tags, the tags only in the first article, the tags only in the second (each list sorted and space-separated, or (none) if empty), and the similarity: shared tags as a percentage of all distinct tags, rounded down (print 0% if there are no tags at all).
For rust web async and web rust cli tui:
shared: rust web
only first: async
only second: cli tui
similarity: 40%
Previous: HashSet: have I seen this before? Next: Your own keys, and grouping