From 516556fb5f15605be38a13f51b4daaf4ec1c03b1 Mon Sep 17 00:00:00 2001 From: Dhghomon <56599343+Dhghomon@users.noreply.github.com> Date: Sun, 26 Jul 2020 19:12:39 +0900 Subject: [PATCH] VecDeque --- README.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/README.md b/README.md index a3b3aa8..776ea7c 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ It is now late July, and *Easy Rust* is about 200 pages long. I am still writing - [HashMap (and BTreeMap)](#hashmap-and-btreemap) - [HashSet and BTreeSet](#hashset-and-btreeset) - [BinaryHeap](#binaryheap) + - [VecDeque](#vecdeque) - [Generics](#generics) - [Option and Result](#option-and-result) - [Result](#result) @@ -3027,6 +3028,74 @@ You need to: Plan who to hire next for the team You need to: Watch some YouTube ``` +## VecDeque + +A `VecDeque` is a `Vec` that is good at popping items both off the front and the back. When you use `.pop()` on a `Vec`, it just takes off the last item on the right and nothing is copied. But if you take it off another part, all the items to the right are copied over. You can see this in the description for `.remove()`: + +```text +Removes and returns the element at position index within the vector, shifting all elements after it to the left. +``` + +So if you do this: + +```rust +fn main() { + let mut my_vec = vec![9, 8, 7, 6, 5]; + my_vec.remove(0); +} +``` + +it will remove `9`. `8` in index 1 will move to index 0, `7` in index 2 will move to index 1, and so on. + +You don't have to worry about that with a `VecDeque`. It is usually a bit slower than a `Vec`, but if you have to do things on both ends then it is a better solution. + +In this example we have a `Vec` of things to do. Then we make a `VecDeque` and use `.push_front()` to put them on the front, so the first item we added will be on the right. But each item we push is a `(&str, bool)`: `&str` is the description and `false` means it's not done yet. We use our `done()` function to pop an item off the back, but we don't want to delete it. Instead, we change `false` to `true` and push it on the front. + +It looks like this: + +```rust +use std::collections::VecDeque; + +fn check_remaining(input: &VecDeque<(&str, bool)>) { // Each item is a (&str, bool) + for item in input { + if item.1 == false { + println!("You must: {}", item.0); + } + } +} + +fn done(input: &mut VecDeque<(&str, bool)>) { + let mut task_done = input.pop_back().unwrap(); // pop off the back + task_done.1 = true; // now it's done - mark as tru + input.push_front(task_done); // put it on the front now +} + +fn main() { + let mut my_vecdeque = VecDeque::new(); + let things_to_do = vec!["send email to customer", "add new product to list", "phone Loki back"]; + + for thing in things_to_do { + my_vecdeque.push_front((thing, false)); + } + + done(&mut my_vecdeque); + done(&mut my_vecdeque); + + check_remaining(&my_vecdeque); + + for task in my_vecdeque { + print!("{:?} ", task); + } +} +``` + +This prints: + +```text +You must: phone Loki back +("add new product to list", true) ("send email to customer", true) ("phone Loki back", false) +``` + ## Generics