How can I get an item from Vec to Rust?

What I need is a method:

fn take<T>(vec: Vec<T>, index: usize) -> Option<T>

However, I cannot find such a method. Am I missing something? Or there is a reason that it is really unsafe / cannot be done correctly.

Edit: is this another question from the Built-in * secure * way to navigate from Vec <T>? There was a method removethat did not panic outside of access (instead, it returned a result). Here I am looking for a method that uses Vec and returns one of the elements. None of the answers to this question apply to my question.

Edit 2: To clarify, I am looking for a method that consumes Vec and returns a single element without the overhead of restoring Vec invariants in the way removeand swap_removedo.

+4
source share
2 answers

You can write your function as follows:

fn take<T>(mut vec: Vec<T>, index: usize) -> Option<T> {
    if vec.get(index).is_none() {
        None
    } else {
        Some(vec.swap_remove(index))
    }
}

This is guaranteed by O (1).


To mention another solution using iterators:

fn take<T>(vec: Vec<T>, index: usize) -> Option<T> {
    vec.into_iter().nth(index)
}

I was going to write this:

Although Iterator::nth()usually a linear time operation, an iterator over a vector overrides this method to make it an O (1) operation.

But then I noticed that this is only true for an iterator that iterates over slices. The iterator std::vec::IntoIterthat will be used in the above code does not cancel nth(). An attempt was made here , but it doesn't seem to be that simple.

So: O (n)!

+7

fn take<T>(vec: Vec<T>, index: usize) -> Option<T> , , . , , Vec<String> 10, 9 1. .

API, , fn take<T>(vec: &mut Vec<T>, index: usize) -> Option<T>.

, , :

  • , , Vec::swap_remove,
  • , - , Vec::drain.

, .


swap_remove:

fn take<T>(mut vec: Vec<T>, index: usize) -> Option<T> {
    if index < vec.len() {
        Some(vec.swap_remove(index))
    } else {
        None
    }
}

drain:

fn take<T>(mut vec: Vec<T>, index: usize) -> Option<T> {
    if index < vec.len() {
        vec.drain(index..index+1).next()
    } else {
        None
    }
}

, : O (1).


, , Vec Vec remove swap_remove do.

- .

, , ; :

  • swap_remove, , ,
  • , , index.

, ; - , ( ), .

-, Vec, ?

swap_remove, 3 :

  • swap_remove (O (1)),
  • (O (N)),
  • .

2 , Drop, , (2) (3) .

TL; DR: , , , .

+1

Source: https://habr.com/ru/post/1684150/


All Articles