Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I convert a HashSet of Strings into a Vector?

I'm trying to convert a HashSet<String> into a sorted vector that can then be joined with commas:

use std::collections::HashSet;

fn main() {
    let mut hs = HashSet::<String>::new();
    hs.insert(String::from("fee"));
    hs.insert(String::from("fie"));
    hs.insert(String::from("foo"));
    hs.insert(String::from("fum"));

    let mut v: Vec<&String> = hs.iter().collect();
    v.sort();

    println!("{}", v.join(", "));
}

This will not compile:

error[E0599]: no method named `join` found for struct `std::vec::Vec<&std::string::String>` in the current scope
  --> src/main.rs:13:22
   |
13 |     println!("{}", v.join(", "));
   |                      ^^^^ method not found in `std::vec::Vec<&std::string::String>`

I understand why I can't join the Vec<&String>, but how can I convert the HashSet to a Vec<String> instead, so it can be joined?

The examples given in What's an idiomatic way to print an iterator separated by spaces in Rust? do not seem to apply because the iterator for Args returns String values, unlike the iterator for HashSet which returns &String.

like image 701
Ralph Avatar asked Mar 27 '20 19:03

Ralph


1 Answers

I encourage you to re-read The Rust Programming Language, specifically the chapter on iterators. Next, become familiar with the methods of Iterator.

The normal way I'd expect to see this implemented is to convert the HashSet to an iterator and then collect the iterator to a Vec:

let mut v: Vec<_> = hs.into_iter().collect();

In this case, I'd prefer to use FromIterator directly (the same trait that powers collect):

let mut v = Vec::from_iter(hs);

Focusing on your larger problem, use a BTreeSet instead, coupled with What's an idiomatic way to print an iterator separated by spaces in Rust?

use itertools::Itertools; // 0.10.1
use std::collections::BTreeSet;

fn main() {
    // Create the set somehow
    let hs: BTreeSet<_> = ["fee", "fie", "foo", "fum"]
        .into_iter()
        .map(String::from)
        .collect();

    println!("{}", hs.iter().format(", "));
}
like image 154
Shepmaster Avatar answered Sep 26 '22 09:09

Shepmaster