Antonin GAVREL
Antonin GAVREL

Reputation: 11219

Remove value if part of vector, and if so accumulate it to another variable

I currently do it this way:

// v is a vector with thousands of sorted unsigned int value.

let mut total = 0;

// [...]
// some loop
    let a = 5;
    if v.iter().any(|&x| x == a as u16) {
        total += a;
        v.retain(|&x| x != a as u16);
    }
// end loop

But it is quite inefficient since I iterate twice over v (although perhaps the compiler would catch this and optimize), isn't it a more elegant way to do it with Rust?

NB: The vector is sorted and contains no duplicate values if it can help

Upvotes: 1

Views: 96

Answers (1)

Stargateur
Stargateur

Reputation: 26717

If I understand correctly your request, here a solution:

fn foo(data: &mut Vec<u16>) -> u64 {
    let mut total: u64 = 0;
    let mut a = 0;

    while data.len() > 0 {
        if let Ok(i) = data.binary_search(&a) {
            total += data.remove(i) as u64;
        }
        a += 1;
    }

    total
}

fn main() {
    let mut data = vec![1, 3, 8, 9, 46];

    assert_eq!(foo(&mut data), 67);
}

This keep the vector sorted while removing, note that this is a dummy example. If you don't care about sorting you can use swap_remove() but this disallow the use of binary_search().

It's hard to say what would be the better.

Upvotes: 4

Related Questions