This question already has answers here:
What's an idiomatic way to print an iterator separated by spaces in Rust?
(4 answers)
How to join elements of HashSet into a String with a delimiter
(2 answers)
Closed 3 years ago.
How can a create a string joining all keys of a hashmap in rust and adding a separator among each of them? I am very new to rust.
In python it would be something like this:
>>> ', '.join({'a':'x', 'b':'y'}.keys())
'a, b'
In Rust, HashMaps are not ordered, so the actual order of the keys in the String will be undefined.
If that is not a problem, you could do it like this:
use std::collections::HashMap;
let mut hm = HashMap::new();
hm.insert("a", ());
hm.insert("b", ());
hm.insert("c", ());
hm.insert("d", ());
hm.insert("e", ());
let s = hm.keys().map(|s| &**s).collect::<Vec<_>>().join(", ");
Playground
Related
This question already has answers here:
Split a string and return Vec<String>
(2 answers)
Closed 2 years ago.
A function I want to use requires a Vec<String> as parameter input.
What I have instead is either a string slice (&str) or a String.
My attempt:
let options_vec: Vec<String> = options.split(char::is_withespace).collect::<Vec<_>>();
The error I'm getting is:
value of type `std::vec::Vec<std::string::String>` cannot be built from `std::iter::Iterator<Item=&str>
split returns impl Iterator<Item = &str>, you need explicitly convert its items to String, for example like this:
let options_vec: Vec<String> = options
.split(char::is_whitespace)
.map(ToString::to_string)
.collect::<Vec<_>>();
This question already has answers here:
How to create a String directly?
(3 answers)
What is the difference between these 3 ways of declaring a string in Rust?
(1 answer)
How do I convert between String, &str, Vec<u8> and &[u8]?
(1 answer)
Closed 2 years ago.
In Rust, there are several ways to create a String from a string literal:
fn main() {
let s_from = String::from("string"); // type on the right of the operator
let s_into: String = "string".into(); // type on the left of the operator
let s_to_string = "string".to_string(); // expresses type
let s_to_owned = "string".to_owned(); // expresses ownership
assert_eq!(s_from, s_into);
assert_eq!(s_from, s_to_string);
assert_eq!(s_from, s_to_owned);
}
Is there a rule in rust to follow a reading direction in relation to the operator?
Is there a reason to favour From/Into over to_string()/to_owned()?
Is there a reason to favour one of those over all the others?
With several developers working on a project, a mixture usage of those happens.
This question already has answers here:
What's an idiomatic way to print an iterator separated by spaces in Rust?
(4 answers)
Closed 3 years ago.
I am trying to apply join (or something similar) to a Vec<char> in order to pretty print it.
What I came up with so far is this (and this does what I want):
let vec: Vec<char> = "abcdef".chars().collect();
let sep = "-";
let vec_str: String = vec
.iter().map(|c| c.to_string()).collect::<Vec<String>>().join(sep);
println!("{}", vec_str); // a-b-c-d-e-f
That seems overly complex (and allocates a Vec<String> that is not really needed).
I also tried to get std::slice::join to work by explicitly creating a slice:
let vec_str: String = (&vec[..]).join('-');
but here the compiler complains:
method not found in &[char]
Is there a simpler way to create a printable String from a Vec<char> with a separator between the elements?
You can use intersperse from the itertools crate.
use itertools::Itertools; // 0.8.2
fn main() {
let vec : Vec<_> = "abcdef".chars().collect();
let sep = '-';
let sep_str : String = vec.iter().intersperse(&sep).collect();
println!("{}", sep_str);
}
Playground
This question already has answers here:
Using the same iterator multiple times in Rust
(2 answers)
How to use the same iterator twice, once for counting and once for iteration?
(3 answers)
How does one have a for loop borrow the iterator?
(3 answers)
Why does Iterator::take_while take ownership of the iterator?
(2 answers)
Closed 3 years ago.
I want to collect a few items from an iterator, then iterate through the rest, something like this:
let iterator = text.split_whitespace();
let first_ten_words = iterator.take(10).collect();
for word in iterator {
// This should iterate over the remaining words.
}
This doesn't work because take() consumes the iterator.
Obviously I can use split_whitespace() twice and skip(10) but I assume that will do the splitting of the first 10 words twice, and therefore be inefficient.
Is there a better way to do it?
You can use .by_ref() like this:
let iterator = text.split_whitespace();
let first_ten_words = iterator.by_ref().take(10).collect();
for word in iterator {
// This should iterate over the remaining words.
}
This question already has answers here:
How can I use the format! macro in a no_std environment?
(5 answers)
A more convenient concatenation with a string literal in Rust
(3 answers)
How to format output to a byte array with no_std and no allocator?
(2 answers)
How to create a static string at compile time
(3 answers)
Closed 3 years ago.
I'm trying to concatenate two strings (&str) or convert a byte array in a string in Rust without using std. I saw core::str::from_utf8 but that's not what I'm looking for.
I'm searching something like
let b: [u8; 2] = [97, 98];
let result: &str = core::str::array_to_string(b); // "ab"
or
let a: &str = "Hello ";
let b: &str = "world !";
let result: &str = core::str::concatenate(a, b);