Reputation: 363
I have three structs:
struct A;
struct B;
struct C {
a: Option<A>,
b: Option<B>
}
Given inputs Vec<A>
and Vec<B>
and some predicate function, I want to create an output Vec<C>
, which is a combination of the elements of the inputs, something like the following:
let aVec: Vec<A> = vec![];
let bVec: Vec<B> = vec![];
let mut cVec: Vec<C> = vec![];
for a in aVec {
if let Some(b) = bVec.into_iter().find(predicate) {
cVec.push(C{a: Some(a), b: Some(b)});
}
}
Is there a way to do this without needing B
to be copyable? Both input vectors aren't required after the operation. Also, is this possible without the loop?
Upvotes: 1
Views: 275
Reputation: 36071
You can:
predicate
. (I would use Iterator::position
.)remove
or swap_remove
the element at the position obtained by the previous step.push
the previously removed element into result.In code:
use itertools; // 0.8.2
use itertools::Itertools;
struct A {}
struct B {
n: usize,
}
struct C {
a: Option<A>,
b: Option<B>
}
fn main() {
let aVec: Vec<A> = vec![];
let mut bVec: Vec<B> = vec![];
let mut cVec: Vec<C> = vec![];
for a in aVec {
if let Some(idx) = bVec.iter()
.position(|b| b.n==42)
{
let b = bVec.remove(idx); // or swap_remove if ordering does not need to be preserved
cVec.push(C{a: Some(a), b: Some(b)});
}
}
}
Upvotes: 2