¿Cuál es la forma más eficiente de implementar máscaras booleanas con vectores en Rust?
Puede haber una caja que haga esto (?), pero para ayudarme a aprender, también me gustaría saber acerca de:
- cómo harías esto sin una caja (es decir, ¿me he perdido algo en la biblioteca estándar?), y;
- si el enmascaramiento booleano se puede extender a listas e iteradores en general.
My example below applies the bool vector [true, false, false, true] to mask out the true indices of a u32 vector [1, 2, 3, 4]. This returns [2, 3].
Estoy usando un bucle for torpe; ¿Podemos hacerlo mejor usando, por ejemplo, mapas e iteradores?
fn main() {
let mut numbers = vec![1, 2, 3, 4];
let mask = vec![true, false, false, true];
remove_true(&mut numbers, &mask); // remove numbers where vector mask == true
println!("{:?}", numbers)
}
// Using a for loop
fn remove_true(vec: &mut Vec<u32>, locs: &Vec<bool>) {
for m in (0..locs.len()).rev() {
// Loop in reverse to preserve indices when dropping values
if locs[m] == true {
vec.remove(m);
}
}
}
Solución del problema
Vec::retain
se puede utilizar para esta operación, de hecho, este tipo de selección es uno de los fragmentos de ejemplo:
let mut vec = vec![1, 2, 3, 4, 5];
let keep = [false, true, true, false, true];
let mut iter = keep.iter();
vec.retain(|_| *iter.next().unwrap());
assert_eq!(vec, [2, 3, 5]);
Dado que está realizando una selección negativa (excluyendo los elementos seleccionados), debe revertir el resultado, pero aparte de eso, es idéntico (de hecho, es un poco más simple porque !
no requiere la eliminación de referencias):
fn remove_true(vec: &mut Vec<u32>, locs: &[bool]) {
let mut drop = locs.into_iter();
vec.retain(|_|!drop.next().unwrap())
}
No hay comentarios.:
Publicar un comentario