Using .map() to run a method on each item and then removing them from vector while the method still runs?

I want to iter over Vector and .dispatch() them if they match condition. Once they have been depatched I want to remove them from the Vector.

I tried using .remove() but then I got an error on .depatch() that the object does not live long enough as I brough it into functions scope. How would a PRO Rustian tackle something like this?

    pub fn dispatch_current_quant_events(&'a mut self) -> bool {
            if self.events.len() == 0 {
           return false
         }

    self.events.iter_mut().map(|e| { 
            if e.quant <= self.current_quant {
                e.dispatch();
                self.events.remove_item(e); // Nightly only. How to remove item in stable channel?
            }
        });
      true
     }

drain_filter is designed for that, but it’s a nightly-only API right now.

However, the documentation shows how to do that without any nightly API. It’s not pretty, but works for now.

1 Like

I am required to build it on Stable. Thanks, I will have a look. I already tried similar approach and I got the can’t use mutable reference more than once error with code like this. That’s why I tried to use .map as this is all done within a single reference. Or atleast that’s what i thoutht

        for i in 0..self.events.len() {
            if self.events.get(i).unwrap().quant <= self.current_quant {
                let event: &'a mut Event = self.events.get_mut(i).unwrap();
                event.dispatch();
                self.events.remove(i);
                continue;
            }
        }

There’s a few crates that provide a retain_mut similar to the standard retain() method…

1 Like

Thanks,
I will look into this.

The other side of the problem is that how can I “wait” with removing the object until the dispatch() has been completed? As I would have to move the Event to a local variable when removing it from the vector and the local variable would die as soon as the function returns.

Well, I don’t know what dispatch does, but from the code above it looked to me like it was a synchronous operation. But while the vector is borrowed mutably during the retain_mut call, nobody else should be able to observe if the event is stil in the vector or not…

By the way, the method above with removing indices won’t work as written since the indices shift after the first remove. You need to either iterate from the back, or adapt i manually.

Something else I’ve used at times was building up another list of indices to remove, and then doing the remove in a different step afterwards. (Depending on the possible size of the vector, the indices can be collected in a stack-allocated bitset.)

1 Like

Thank you Birkenfield

You can take a look at the entire code here