Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Build HashSet from a vector in Rust

I want to build a HashSet<u8> from a Vec<u8>. I'd like to do this

  1. in one line of code,
  2. copying the data only once,
  3. using only 2n memory,

but the only thing I can get to compile is this piece of .. junk, which I think copies the data twice and uses 3n memory.

fn vec_to_set(vec: Vec<u8>) -> HashSet<u8> {     let mut victim = vec.clone();     let x: HashSet<u8> = victim.drain(..).collect();     return x; } 

I was hoping to write something simple, like this:

fn vec_to_set(vec: Vec<u8>) -> HashSet<u8> {     return HashSet::from_iter(vec.iter()); } 

but that won't compile:

error[E0308]: mismatched types  --> <anon>:5:12   | 5 |     return HashSet::from_iter(vec.iter());   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected u8, found &u8   |   = note: expected type `std::collections::HashSet<u8>`   = note:    found type `std::collections::HashSet<&u8, _>` 

.. and I don't really understand the error message, probably because I need to RTFM.

like image 529
Jared Beck Avatar asked Oct 01 '16 05:10

Jared Beck


People also ask

How do you get a value from a vector in Rust?

Rust provides us with two methods to access elements in a vector. We can access values with either the indexer, or with the get() method.

How do you initialize VEC in Rust?

In Rust, there are several ways to initialize a vector. In order to initialize a vector via the new() method call, we use the double colon operator: let mut vec = Vec::new(); This call constructs a new, empty Vec<T> .

How do vectors work in Rust?

Vector is a module in Rust that provides the container space to store values. It is a contiguous resizable array type, with heap-allocated contents. It is denoted by Vec<T>. Vectors in Rust have O(1) indexing and push and pop operations in vector also take O(1) complexity.

What is a HashSet in Rust?

Introduction to Rust hashset. A collection that is used to hold a unique value inside it while not allowing the duplicate values inside the collection is called a HashSet on Rust.


1 Answers

Because the operation does not need to consume the vector¹, I think it should not consume it. That only leads to extra copying somewhere else in the program:

use std::collections::HashSet; use std::iter::FromIterator;  fn hashset(data: &[u8]) -> HashSet<u8> {     HashSet::from_iter(data.iter().cloned()) } 

Call it like hashset(&v) where v is a Vec<u8> or other thing that coerces to a slice.

There are of course more ways to write this, to be generic and all that, but this answer sticks to just introducing the thing I wanted to focus on.

¹This is based on that the element type u8 is Copy, i.e. it does not have ownership semantics.

like image 140
bluss Avatar answered Sep 17 '22 17:09

bluss