illustrator - labels vector free download
¿Cómo se procesa un rango en rodajas en Rust? (1)
Use chunks
(o chunks_mut
si necesita mutabilidad):
fn main() {
let things = [5, 4, 3, 2, 1];
for slice in things.chunks(2) {
println!("{:?}", slice);
}
}
Productos:
[5, 4]
[3, 2]
[1]
La forma más sencilla de combinar esto con un Range
sería recolectar el rango a un Vec
primero (que se desreferencia a un segmento):
fn main() {
let things: Vec<_> = (1..100).collect();
for slice in things.chunks(5) {
println!("{:?}", slice);
}
}
Otra solución que es iterador puro sería usar Itertools::chunks_lazy
:
extern crate itertools;
use itertools::Itertools;
fn main() {
for chunk in &(1..100).chunks_lazy(5) {
for val in chunk {
print!("{}, ", val);
}
println!("");
}
}
Lo que sugiere una solución similar que solo requiere la biblioteca estándar:
fn main() {
let mut range = (1..100).peekable();
while range.peek().is_some() {
for value in range.by_ref().take(5) {
print!("{}, ", value);
}
println!("");
}
}
Un truco es que Ruby y Rust tienen un manejo diferente aquí, principalmente centrado en la eficiencia.
En Ruby, Enumerable
puede crear nuevas matrices para rellenar los valores sin preocuparse por la propiedad y devolver una nueva matriz cada vez (verifique con this_slice.object_id
).
En Rust, asignar un nuevo vector cada vez sería bastante inusual. Además, no puede devolver fácilmente una referencia a un vector que contiene el iterador debido a preocupaciones complicadas de por vida.
Una solución que es muy similar a la de Ruby es:
fn main() {
let mut range = (1..100).peekable();
while range.peek().is_some() {
let chunk: Vec<_> = range.by_ref().take(5).collect();
println!("{:?}", chunk);
}
}
Que podría incluirse en un nuevo iterador que oculta los detalles:
use std::iter::Peekable;
struct InefficientChunks<I>
where I: Iterator
{
iter: Peekable<I>,
size: usize,
}
impl<I> Iterator for InefficientChunks<I>
where I: Iterator
{
type Item = Vec<I::Item>;
fn next(&mut self) -> Option<Self::Item> {
if self.iter.peek().is_some() {
Some(self.iter.by_ref().take(self.size).collect())
} else {
None
}
}
}
trait Awesome: Iterator + Sized {
fn inefficient_chunks(self, size: usize) -> InefficientChunks<Self> {
InefficientChunks {
iter: self.peekable(),
size: size,
}
}
}
impl<I> Awesome for I where I: Iterator {}
fn main() {
for chunk in (1..100).inefficient_chunks(5) {
println!("{:?}", chunk);
}
}
Entiendo que la forma preferida de iterar en Rust es mediante la sintaxis de for var in (range)
, pero a veces me gustaría trabajar en más de uno de los elementos de ese rango a la vez.
Desde la perspectiva de Ruby, estoy tratando de encontrar una forma de hacer (1..100).each_slice(5) do |this_slice|
en Rust.
Estoy intentando cosas como
for mut segment_start in (segment_size..max_val).step_by(segment_size) {
let this_segment = segment_start..(segment_start + segment_size).iter().take(segment_size);
}
pero sigo recibiendo errores que sugieren que estoy ladrando el error tipo árbol. Los documentos tampoco son útiles; simplemente no contienen este caso de uso.
¿Cuál es la forma de óxido para hacer esto?