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.
}
Related
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:
How to write a Rust function that takes an iterator?
(3 answers)
What is the correct way to return an Iterator (or any other trait)?
(2 answers)
Closed 3 years ago.
Let's say I have an iterator like this:
let it = text.char_indices().take(x).skip(y);
Then I want to pass it to a function my_func. Currently I have a parameter like this:
fn my_func(it: std::iter::Skip<std::iter::Take<std::str::CharIndices>>) {
}
Is there a shorter way to write the type? Also, the function shouldn't really require that all iterator parameters now must be derived from .skip and .take and in this exact order.
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
This question already has answers here:
What's the difference between len() and capacity()?
(2 answers)
How to allocate space for a Vec<T> in Rust?
(3 answers)
How do I generate a vector of random numbers in a range?
(2 answers)
Closed 3 years ago.
I am trying to populate a vector after initialising it with with_capacity() as the number of elements is known prior to its creation and it seems more efficient with it.
The following code does NOT populate with random values AT ALL: println!("{}", v.len()); outputs zero.
use rand::Rng;
fn main() {
const NUMBER_OF_RANDOM_NUMBERS: usize = 10;
let mut v = Vec::with_capacity(NUMBER_OF_RANDOM_NUMBERS);
for i in &mut v {
*i += rand::thread_rng().gen_range(1, 2^32);
}
println!("{}", v.len());
}
My thinking is after let mut v = Vec::with_capacity(NUMBER_OF_RANDOM_NUMBERS) a brand new vector gets initialised with 10 zeros and then using rand::thread_rng().gen_range(1, 2^32) to insert, or should I say, add a random number to each zero.
Am I missing something here?
with_capacity does not initialize the values of the vector, it just allocates space for them. From the documentation:
It is important to note that although the returned vector has the
capacity specified, the vector will have a zero length. For an
explanation of the difference between length and capacity, see
Capacity and reallocation.
This means that when your loop code is executed, there are no items in the vector, and therefore it loops a total of zero times. Resulting in no change in the vector.
This question already has an answer here:
How to swap the elements of an array, slice, or Vec?
(1 answer)
Closed 5 years ago.
I would like to swap String elements of a vector
let mut v_sa: Vec<String> = vec![];
...
let temp_a = v_sa_ib[j];
v_sa_ib[j] = v_sa_ib[j+1];
v_sa_ib[j+1] = temp_a;
It works with integers but not with Strings. I also tried to create a second vector temp_b (same type of temp_a) and to populate it instead of swapping but i got always the same error: the type of this value must be known in this context.
How can I fix it?
You can use the swap() method of Vec to swap two elements directly:
v_sa_ib(j, j+1);
There is also a generic swap function called std::mem::swap but it is difficult to use here because obtaining two mutable references two different elements of the same Vec is quite involved.
The reason why it worked with integers is that integers implement the Copy trait, so Rust can automatically create new copies.