keponk
keponk

Reputation: 320

How do I match a vector of tuples and its content using a single check?

I want to match a vector of tuples and its content using a single check. If the value inside the tuple is equal to some_value (a usize) then I do something, for every other case I do something else.

I handle it like this with basic logic:

if myvector.is_empty() {
    // do action 1
} else if myvector.last().unwrap().0 == some_value {
    // do action 2
} else {
    // do action 1
}

This does what I want, but I feel there's a more idiomatic way to do it. I've been trying with match:

match myvector.last() {
    Some(t) => match t.0 == some_value {
        true => unimplemented!("do action 2"),
        false => unimplemented!("do action 1"),
    },
    None => unimplemented!("do action 1"),
}

This also works, but I'm trying to figure out a better syntax to cover a single case once only (action1).

Upvotes: 0

Views: 1572

Answers (3)

Stargateur
Stargateur

Reputation: 26765

I would do:

if let Some(_) = my_vector.last().filter(|(n, _)| n == some_value) {
    // do action 2
} else {
    // do action 1
}

Upvotes: 1

keponk
keponk

Reputation: 320

I got the following to work:

match myvector.last() {
    Some(t) if t.0 == some_value => unimplemented!("do action2"),
    _ => unimplemented!("do action1"),
}

Upvotes: 2

user4815162342
user4815162342

Reputation: 155590

You can use a slice pattern to extract the last element, and deconstruct the tuple directly in the pattern:

fn test_last(v: &[(u32, u32)], testval: u32) -> u32 {
    match v {
        [.., (val, _)] if *val == testval => {
            // action 2
        }
        _ => {
            // action 1
        }
    }
}

Playground

Upvotes: 3

Related Questions