Is there any way to accomplish something like the following:
let v = vec![1, 2, 3];
let (a, b) = v.iter().take(2);
Such that a = 1
and b = 2
at the end?
I know I could just use a vector but I would like to have named variables.
Unpacking a tuple means splitting the tuple's elements into individual variables. For example: x, y = (1, 2) Code language: Python (python)
'tuple' object is not an iterator.
When we are unpacking values into variables using tuple unpacking, the number of variables on the left side tuple must exactly match the number of values on the right side tuple . Otherwise, we'll get a ValueError .
Because parentheses of tuples can be omitted, multiple values can be assigned to multiple variables in one line as follows. An error is raised if the number of variables does not match the number of elements.
The itertools crate has methods like tuples
and next_tuple
that can help with this.
use itertools::Itertools; // 0.9.0
fn main() {
let v = vec![1, 2, 3];
let (a, b) = v.iter().next_tuple().unwrap();
assert_eq!(a, &1);
assert_eq!(b, &2);
}
This may not be exactly what you asked for, but I suppose you rarely want to convert an arbitrarily large vector to a tuple anyway. If you just want to extract the first few elements of a vector into a tuple, you can do so using slice pattern matching:
fn main() {
let v = vec![1, 2, 3];
let (a, b) = match &v[..] {
&[first, second, ..] => (first, second),
_ => unreachable!(),
};
assert_eq!((a, b), (1, 2));
}
I wrote this ugly recursive macro that converts a Vec
to a tuple because I wanted to learn something about macros.
macro_rules! tuplet {
{ ($y:ident $(, $x:ident)*) = $v:expr } => {
let ($y, $($x),*) = tuplet!($v ; 1 ; ($($x),*) ; ($v[0]) );
};
{ $v:expr ; $j:expr ; ($y:ident $(, $x:ident)*) ; ($($a:expr),*) } => {
tuplet!( $v ; $j+1 ; ($($x),*) ; ($($a),*,$v[$j]) )
};
{ $v:expr ; $j:expr ; () ; $accu:expr } => {
$accu
}
}
I am new to this and probably very bad at it, so there's most likely a better way to do it. This is just a proof of concept. It allows you to write:
fn main() {
let v = vec![1, 2, 3];
tuplet!((a, b, c) = v);
assert_eq!(a, 1);
assert_eq!(b, 2);
assert_eq!(c, 3);
}
Somewhere in that macro definition you find the part $v[$j]
, which you could replace by $v.nth($j)
if you want to use it for iterators.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With