# How to delete element when iterating a vec?

**URL:** <https://users.rust-lang.org/t/how-to-delete-element-when-iterating-a-vec/65862>\
**Category:** uncategorized\
**Created:** [October 13, 2021, 12:03pm UTC](https://users.rust-lang.org/t/how-to-delete-element-when-iterating-a-vec/65862 "2021-10-13T12:03:05Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![harlanc](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/harlanc/32/20575_2.png) [@harlanc](https://users.rust-lang.org/u/harlanc)\
**Post date:** [October 13, 2021, 12:03pm UTC](https://users.rust-lang.org/t/how-to-delete-element-when-iterating-a-vec/65862/1 "2021-10-13T12:03:05Z")

</div>

For example the following codes will throw exception:index out of bounds: the len is 3 but the index is 3

```
   let mut vecc = vec![1, 2, 3, 4];

    for i in 0..vecc.len() {
        if vecc[i] == 1 {
            vecc.remove(i);
        }
    }

```

---

<div class="post-metadata">

**Author:** ![jkugelman](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/jkugelman/32/15839_2.png) [@jkugelman](https://users.rust-lang.org/u/jkugelman)\
**Post date:** [October 13, 2021, 12:12pm UTC](https://users.rust-lang.org/t/how-to-delete-element-when-iterating-a-vec/65862/2 "2021-10-13T12:12:54Z")

</div>

Mutating while iterating is a tough sell in many languages, Rust among them. It's doable, but I would try to find a way not to. There's often a method you can call to avoid an explicit loop, such as [`retain`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.retain) for your example:

```rust
vecc.retain(|&i| i != 1);

```

[Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7f8c1dfc44f3fed0f9c012507371ce3f)

---

<div class="post-metadata">

**Author:** ![harlanc](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/harlanc/32/20575_2.png) [@harlanc](https://users.rust-lang.org/u/harlanc)\
**Post date:** [October 13, 2021, 12:17pm UTC](https://users.rust-lang.org/t/how-to-delete-element-when-iterating-a-vec/65862/3 "2021-10-13T12:17:08Z")

</div>

The following can also work:

```
    let mut vecc = vec![1, 2, 3, 4];
    let mut idx = 0 as usize;

    while idx < vecc.len() {
        if vecc[idx] == 1 {
            vecc.remove(idx);
            continue;
        }
        idx = idx + 1;
    }

```

---

<div class="post-metadata">

**Author:** ![harlanc](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/harlanc/32/20575_2.png) [@harlanc](https://users.rust-lang.org/u/harlanc)\
**Post date:** [October 13, 2021, 12:17pm UTC](https://users.rust-lang.org/t/how-to-delete-element-when-iterating-a-vec/65862/4 "2021-10-13T12:17:59Z")

</div>

It is great!

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/steffahn/32/47569_2.png) [@steffahn](https://users.rust-lang.org/u/steffahn)\
**Post date:** [October 13, 2021, 12:43pm UTC](https://users.rust-lang.org/t/how-to-delete-element-when-iterating-a-vec/65862/5 "2021-10-13T12:43:24Z")

</div>

Note that calling `remove` in a loop is also more inefficient. `Vec::remove` takes linear1 time (it has to _shift_ all the elements to the right of the removed element one to the left in memory); thus calling `.remove` in a loop can take quadratic1 time; whereas `.retain` only takes linear1, 2 time for the whole process (it can use an implementation that – as an intermediate state – leaves some “slots” of memory empty during the iteration, with the effect of only having to move each item of the vec at most once).

1 linear/quadratic with respect to the length of the vector  
2 assuming that the closure given to `.retain` only needs constant time

---

<div class="post-metadata">

**Author:** ![2e71828](https://avatars.discourse-cdn.com/v4/letter/2/3e96dc/32.png) [@2e71828](https://users.rust-lang.org/u/2e71828)\
**Post date:** [October 13, 2021, 3:36pm UTC](https://users.rust-lang.org/t/how-to-delete-element-when-iterating-a-vec/65862/6 "2021-10-13T15:36:22Z")

</div>

> [@steffahn](#):
>
> (it can use an implementation that – as an intermediate state – leaves some “slots” of memory empty during the iteration, with the effect of only having to move each item of the vec at most once).

To translate this into code, `Vec::retain()` works similarly¹ to this:

```rust
    let mut vecc = vec![1, 2, 3, 4];

    let mut idx_wr = 0usize;
    for idx_rd in 0..vecc.len() {
        if ! (vecc[idx_rd] == 1) {
            vecc.swap(idx_wr, idx_rd);
            idx_wr += 1;
        }
    }
    
    vecc.truncate(idx_wr);

```

¹ I haven't looked at the actual code for `retain`; it probably uses `unsafe` to perform a move instead of the `swap` call I used.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/steffahn/32/47569_2.png) [@steffahn](https://users.rust-lang.org/u/steffahn)\
**Post date:** [October 13, 2021, 3:38pm UTC](https://users.rust-lang.org/t/how-to-delete-element-when-iterating-a-vec/65862/7 "2021-10-13T15:38:35Z")

</div>

> [@2e71828](#):
>
> ¹ I haven't looked at the actual code for `retain` ; it probably uses `unsafe` to perform a move instead of the `swap` call I used.

yup, that’s exactly what it does.

---

<div class="post-metadata">

**Author:** ![system](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/system/32/51372_2.png) [@system](https://users.rust-lang.org/u/system)\
**Post date:** [January 11, 2022, 3:38pm UTC](https://users.rust-lang.org/t/how-to-delete-element-when-iterating-a-vec/65862/8 "2022-01-11T15:38:38Z")

</div>

Closed on January 11, 2022, 3:38pm UTC

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.
