ideasman42
ideasman42

Reputation: 48228

How to a swap only some members of a struct in a vector?

Vectors have a method to swap entire items:

my_vector.swap(i, j)

For a vector of large structs, I want to swap only some of the data in each struct.

What would be a rustic way to swap only some members of the struct?

Upvotes: 0

Views: 271

Answers (1)

DK.
DK.

Reputation: 59125

You need to break the slice into disjoint subsets using [_]::split_at_mut. This can be used to get &mut _s to the structures. At that point, you can just mem::swap the elements as needed.

#[derive(Debug)]
struct Big {
    small: i32,
    tiny: u8,
}

fn swap_smalls(bigs: &mut [Big], i: usize, j: usize) {
    use std::cmp::{max, min};
    use std::mem::swap;

    if i == j { return; }
    let (i, j) = (min(i, j), max(i, j));

    let (left_slice, right_slice) = bigs.split_at_mut(j);
    let left = &mut left_slice[i];
    let right = &mut right_slice[0];

    swap(&mut left.small, &mut right.small);
}

fn main() {
    let mut bigs = vec![
        Big { small: 4, tiny: 31 },
        Big { small: 0, tiny: 2 },
        Big { small: -7, tiny: 193 },
    ];

    println!("before: {:?}", bigs);
    swap_smalls(&mut bigs, 0, 2);
    println!("after:  {:?}", bigs);
}

Outputs:

before: [Big { small: 4, tiny: 31 }, Big { small: 0, tiny: 2 }, Big { small: -7, tiny: 193 }]
after:  [Big { small: -7, tiny: 31 }, Big { small: 0, tiny: 2 }, Big { small: 4, tiny: 193 }]

"rustic" implies there are multiple solutions, but I don't think there are, so it's not really relevant.

Upvotes: 3

Related Questions