Index of first element in Slice satisfying a property

I'm aware of https://doc.rust-lang.org/std/primitive.slice.html

I'm looking for a function of type signature

slice: &[T]
pred: &T -> bool
returns: Option<usize>

where it returns the index of the first element in the slice satisfying pred

Does such a primitive exist?

EDIT: usize -> Option<usize>

std::iter::Iterator::position doesn't explicitly take a slice as argument but it seems to fit your need.

6 Likes

@leudz Beat me to it, but here's an example of what it does:

let v = vec![1, 3, 5, 7, 9, 0, 2, 4, 6, 8];
let ind = v.iter().position(|x| x % 2 == 0);
if let Some(x) = ind {
   println!("{:?}", &v[ind..]);
}

I would post a playground link but it seems to be utterly unusable for me on mobile right now.

5 Likes

For the sake of completeness regarding people with similar needs, there is also:

  • Iterator::rposition() when looking for the "last" occurence;

  • Regarding iteration of a str's chars (instead of bytes), things like .enumerate() and .position() must be avoided if the usize is to be used to index the str. Indeed, the i-th char does not have to be at the i-th byte (except when i = 0 :stuck_out_tongue:), since the UTF-8 encoding of a Unicode char may not be 1-byte long. For such situations, the *_indices methods should be used (such as .match_indices()):

    • /// Return the index of the first occurence of a char matching
      /// predicate, if any.
      fn str_find (
          s: &'_ str,
          predicate: impl FnMut(char) -> bool,
      ) -> Option<usize>
      {
          // rmatch_indices for an rfind
          s.match_indices(predicate).next().map(|(i, _)| i)
      }
      
    • and in the same vein, .char_indices() ought to be used rather than .chars().enumerate()

5 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.