Alexey Mirano
Alexey Mirano

Reputation: 53

pass multiple arguments to the ends_with function

I can do this without any problems:

"hello".ends_with("o"); //true

However, I would like to compare the end of the line with several variants:

let endings = vec!["o", "a"];

fn check_str(s: &str, e: Vec<&str>) -> bool {
    s.ends_with(e)
}

check_str("some...", endings); //true or false

Is it possible to do this without resorting to iterating over an array or vector with for?

Upvotes: 0

Views: 271

Answers (2)

Masklinn
Masklinn

Reputation: 42342

Is it possible to do this without resorting to iterating over an array or vector with for?

Depends.

If you're only looking for single characters, then yes: the signature of str::ends_with is

pub fn ends_with<'a, P>(&'a self, pat: P) -> bool where
    P: Pattern<'a>,
    <P as Pattern<'a>>::Searcher: ReverseSearcher<'a>, 

This means anything which implements Pattern works. Pattern is an unstable API so you only get what the standard library implements, which is:

  • strings of any form -> single substring
  • char -> contained in string
  • Fn(char) -> bool -> function returns true
  • slice of char -> any of the chars

The last one would be your "in":

fn main() {
    let endings = vec!['o', 'a'];
    for s in &["some...", "strings", "ends", "with", "carbonara"] {
        dbg!(s.ends_with(endings.as_slice()));
    }
}

If you need something more complex (e.g. multiple actual substrings), then iteration is your only option.

However that doesn't mean you have

resorting to iterating over an array or vector with for?

Rust has great support for iterators, so you can write something like:

endings.iter().any(|n| s.ends_with(*n))

And this will return true/false depending on s ending with any of endings's values.

Upvotes: 2

prog-fh
prog-fh

Reputation: 16925

If you don't want to iterate by yourself with for, you can use a functional style, but it will iterate internally, however.

fn check_str(
    s: &str,
    endings: &[&str],
) -> bool {
    endings.iter().any(|e| s.ends_with(e))
}

fn main() {
    let endings = vec!["o", "a"];

    println!("{}", check_str("some...", &endings));
    println!("{}", check_str("hello", &endings));
    println!("{}", check_str("voila", &endings));
}
/*
false
true
true
*/

Upvotes: 2

Related Questions