HashSet

Последнее обновление: 09.05.2024

Тип HashSet представляет множество - коллекцию, которая хранит только уникальные элементы. Данный тип определен в модуле std::collections:

use std::collections::HashSet;

Тип HashSet типизируется типом элементов, которые помещаются во множество:

let mut my_set: HashSet<i32>;

В данном случае множество my_set предназначено для хранения значений типа i32.

Для создания пустого множества можно использовать метод new():

let mut my_set: HashSet<i32> = HashSet::new();

Можно создать множество на основе других коллекций, например, вектора и массива

use std::collections::HashSet;

fn main() { 

    let my_vector = vec![1, 2, 3, 4];
    let my_set: HashSet<i32> = my_vector.into_iter().collect(); // множество из вектора
    println!("my_set: {:?}", my_set);       // my_set: {1, 3, 2, 4}

    let my_array = [5, 6, 7];
    let my_set2 = HashSet::from(my_array);  // множество из массива
    println!("my_set2: {:?}", my_set2);     // my_set2: {5, 6, 7}
}

Обратите внимание, что множество может содержать только уникальные значения. Поэтому если мы добавляем во множество повторяющиеся значения или создаем множество на основе наборов, которые содержат повторяющиеся значения, то такое множество все равно будет содержать только уникальные значения:

use std::collections::HashSet;

fn main() { 

    let my_set = HashSet::from([1, 2, 3, 4, 5, 3, 2, 4]);
    println!("my_set: {:?}", my_set);     // my_set: {4, 3, 1, 5, 2}
}

Для получения длины множества применяется встроенная функция len():

use std::collections::HashSet;

fn main() { 

    let my_set = HashSet::from([1, 2, 3, 4, 5]);
    println!("my_set len: {}", my_set.len());     // my_set len: 5
}

Добавление элементов

Для добавления одиночного элемента вызывается метод insert():

use std::collections::HashSet;

fn main() { 

    let mut users: HashSet<&str> = HashSet::new();
    users.insert("Tom");
    users.insert("Bob");
    users.insert("Sam");
    println!("{:?}", users);     // {"Tom", "Bob", "Sam"}
}

Стоит отметить, что для изменения множества (как и для изменения других значений) переменная множества должна быть объявлена с ключевым словом mut

Удаление элементов

Для удаления одного элемента вызывается метод remove(), в который передается удаляемый элемент. Причем удаляемый элемент должен передаваться как ссылка:

use std::collections::HashSet;

fn main() { 

    let mut users = HashSet::from(["Tom", "Bob", "Alice"]);
    users.remove("Tom");
    users.remove("Sam");    // "Sam" нет в множестве, поэтому никакого эффекта не происходит
    println!("{:?}", users);     // {"Bob", "Alice"}
}

Стоит отметить, что здесь множество хранит ссылки &str, так как строка по умолчанию представляет данный тип. Однако если элементы не представляют ссылки, то нам надо указывать символ ссылки (амперанд):

use std::collections::HashSet;

fn main() { 
    let mut numbers = HashSet::from([1, 2, 3, 4]);
    numbers.remove(&2);
    println!("{:?}", numbers);     // {3, 1, 4}
}

Для удаления всех элементов вызывается метод clear():

let mut users = HashSet::from(["Tom", "Bob", "Alice"]);
users.clear();

Перебор множества

Для перебора элементов можно использовать цикл for:

use std::collections::HashSet;

fn main() { 

    let users = HashSet::from(["Tom", "Bob", "Alice"]);
    for user in &users{
        println!("{}", user);
    }
}

При переборе каждый элемент помещается в переменную user.

Операции с множествами

Объединение множеств

Метод union() объединяет два множества:

use std::collections::HashSet;

fn main() { 

    let users = HashSet::from(["Tom", "Bob", "Alice"]);
    let users2 = HashSet::from(["Sam", "Kate", "Bob"]);

    let users3: HashSet<_> = users.union(&users2).collect();
    println!("{:?}", users3);  // {"Sam", "Bob", "Alice", "Kate", "Tom"}

}

Пересечение множеств

Пересечение множеств позволяет получить только те элементы, которые есть одновременно в обоих множествах. Метод intersection() производит операцию пересечения множеств:

use std::collections::HashSet;

fn main() { 

    let users = HashSet::from(["Tom", "Bob", "Alice"]);
    let users2 = HashSet::from(["Sam", "Kate", "Bob"]);

    let users3: HashSet<_> = users.intersection(&users2).collect();
    println!("{:?}", users3);  // {"Bob"}
}

Разность множеств

Еще одна операция - разность множеств возвращает те элементы, которые есть в первом множестве, но отсутствуют во втором. Для получения разности множеств можно использовать метод difference():

use std::collections::HashSet;

fn main() { 

    let users = HashSet::from(["Tom", "Bob", "Alice"]);
    let users2 = HashSet::from(["Sam", "Kate", "Bob"]);

    let users3: HashSet<_> = users.difference(&users2).collect();
    println!("{:?}", users3);  // {"Alice", "Tom"}
}

Отдельная разновидность разности множеств - симметрическая разность производится с помощью метода symmetric_difference(). Она возвращает все элементы обоих множеств за исключением общих:

use std::collections::HashSet;

fn main() { 

    let users = HashSet::from(["Tom", "Bob", "Alice"]);
    let users2 = HashSet::from(["Sam", "Kate", "Bob"]);

    let users3: HashSet<_> = users.symmetric_difference(&users2).collect();
    println!("{:?}", users3);  // {"Tom", "Kate", "Alice", "Sam"}
}

Отношения между множествами

Метод is_subset позволяет выяснить, является ли текущее множество подмножеством (то есть частью) другого множества:

use std::collections::HashSet;

fn main() { 

    let users = HashSet::from(["Tom", "Bob", "Alice"]);
    let superusers = HashSet::from(["Sam", "Tom", "Bob", "Alice", "Kate"]);

    println!("{}", users.is_subset(&superusers));   // true
    println!("{}", superusers.is_subset(&users));   // false
}

Метод is_superset(), наоборот, возвращает true, если текущее множество является надмножеством (то есть содержит) для другого множества:

use std::collections::HashSet;

fn main() { 

    let users = HashSet::from(["Tom", "Bob", "Alice"]);
    let superusers = HashSet::from(["Sam", "Tom", "Bob", "Alice", "Kate"]);

    println!("{}", users.is_superset(&superusers));   // false
    println!("{}", superusers.is_superset(&users));   // true
}

Это только небольшой перечень методов HashSet. Полный список методов можно найти в документации на странице https://doc.rust-lang.org/std/collections/struct.HashSet.html.

Помощь сайту
Юмани:
410011174743222
Номер карты:
4048415020898850