Branching a iterator without deep copying its elements

Viewed 271

Iterators is consumed by map, so require cloned(equals to clone?) when mapping a iterator multiple times. I have following code:

fn main() {
    let a: Vec<(&str, (&i32, &i32))> = vec![("0", (&0, &1)), ("1", (&2, &3))];
    let iter = a.iter().map(|x| x.1 as (&i32, &i32));

    // occur clone process on i32?
    let xs: Vec<&i32> = iter.cloned().map(|(x, _)| x).collect();
    
    let ys: Vec<&i32> = iter.map(|(_, y)| y).collect();
    println!("{:?}", xs);
    println!("{:?}", ys);
}

The problem is that cloned method probably deep copy whole an iterated element even though the elements contain immutable references. Cloned elements is i32 in above, but it may actually have big structure. I want to explicitly shallow copy elements which contain references to i32 (actually bigger struct) when branch iterator iter. Is it possible?

1 Answers

Use clone instead of cloned:

fn main() {
    let a: Vec<(&str, (&i32, &i32))> = vec![("0", (&0, &1)), ("1", (&2, &3))];
    let iter = a.iter().map(|x| x.1 as (&i32, &i32));

    // occur clone process on i32?
    let xs: Vec<&i32> = iter.clone().map(|(x, _)| x).collect();
    
    let ys: Vec<&i32> = iter.map(|(_, y)| y).collect();
    println!("{:?}", xs);
    println!("{:?}", ys);
}

Playground

clone clones the iterator itself. Meanwhile cloned clones the underlying elements, from the documentation:

Cloned: An iterator that clones the elements of an underlying iterator.

Related