Start learning free

LESSON 117 OF 679 · ARRAYS I

Checking a Vec for a Value in Rust

Lesson Read the full explanation

TL ; DR:

v.contains(&x) is true when the Vec holds x, and false when it doesn't. Note the & before the value.


let colors = vec!["red", "green", "blue"];

println!("{}", colors.contains(&"red"));    // true

println!("{}", colors.contains(&"pink"));   // false

if !colors.contains(&"pink") {
    println!("No pink yet");
}


Full lesson:

Often you need to know if a Vec holds some value. Is this name on the guest list? Is this item in the cart?

contains answers that. It compares each item with the value, from the first one on. It returns true as soon as one matches, or false if none does.

It wants a reference to the value, not the value itself. So write & before it, as in colors.contains(&"red"). Without the &, the code doesn't compile.

Put ! in front for the opposite. So !colors.contains(&x) is true when x is missing.

The answer is a bool, so it fits right into an if:

let cart = vec!["milk", "bread"];

if cart.contains(&"milk") {
    println!("Milk is in the cart");
}

Text must match exactly. So colors.contains(&"Red") is false, because the Vec has "red".


Your task

bag holds what is packed for a hike.

If "water" is in bag, print Water is packed. If "tent" is not in bag, print Pack a tent.

Expected output:

Water is packed
Pack a tent
STEP 1 OF 2
    Ctrl + Enter to check

    RUST · ARRAYS I

    Array Membership in Rust, explained

    Asking whether a value is there

    Often you need to know whether a Vec holds some value: is this name on the guest list, is this item in the cart? The method contains answers that with a bool. It compares the items with the value from the first one on, returns true as soon as one matches, and returns false if none does.

    let colors = vec!["red", "green", "blue"];
    
    println!("{}", colors.contains(&"red"));    // true
    println!("{}", colors.contains(&"pink"));   // false
    

    A run prints true and then false.

    Why the &

    contains takes a reference to the value, not the value itself, so you write & in front of it. Without it the code doesn't compile. For a vector of &str, colors.contains("red") is rejected with "expected &&str, found &str"; the vector's items are &str, so the argument must be a reference to one.

    The same goes for other item types. With a Vec<i32> you write nums.contains(&8). With a Vec<String> and a String variable called name, you write names.contains(&name).

    Using it in an if

    The answer is a bool, so it goes right into an if. Put ! in front for the opposite: !colors.contains(&x) is true when x is missing.

    let cart = vec!["milk", "bread"];
    
    if cart.contains(&"milk") {
        println!("Milk is in the cart");
    }
    

    Text must match exactly, upper and lower case included. colors.contains(&"Red") is false, because the vector has "red".

    Details worth knowing

    An empty vector never contains anything, so contains is false for it. A vector with repeated values is fine: vec![4, 4, 4].contains(&4) is true, and the search stops at the first match.

    A common use is to add an item only when it is new. If seen is a Vec<&str> and w is "b", then if !seen.contains(&w) { seen.push(w); } adds "b" the first time and does nothing the second time, so seen ends as ["a", "b"]. When you need the position of a value rather than a yes or no, a different method is needed; contains only answers the question "is it there?".

    The task, step by step

    The bag is ["map", "water", "snacks"]. The first check asks whether it holds "water", and the print runs when it does. The second check asks whether it does not hold "tent", using !, and prints Pack a tent when that is true.

    let bag = vec!["map", "water", "snacks"];
    if bag.contains(&"water") {
        println!("Water is packed");
    }
    if !bag.contains(&"tent") {
        println!("Pack a tent");
    }
    

    It prints:

    Water is packed
    Pack a tent
    

    Why two separate ifs

    The two checks in the task are independent questions, so they are two separate if blocks, not an if with an else. The bag does hold water, so the first message prints. The bag does not hold a tent, so the second condition, !bag.contains(&"tent"), is true and its message prints as well. An else would only run when the first check failed, which is not what the task asks for. Reading the condition aloud helps: "if the bag does not contain a tent".

    Common mistakes

    • Leaving out the &, which is a compile error.
    • Putting the ! in the wrong place. It goes before the whole call: !bag.contains(&"tent").
    • Expecting a match on different capitalisation, such as "Water" for "water".

    Key takeaways

    • v.contains(&x) is true when the vector holds x.
    • Write !v.contains(&x) for "x is missing".
    • The match is exact, and the argument is always a reference.
    Keep going with Rust500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free