Kill KRT
Kill KRT

Reputation: 1261

Find and push element in a vector in the same method

I've the feeling that my implementation is too cumbersome and I guess there is a better way to implement this simple thing.

I have a Grid struct representing a game board, I have a method to add a cell into grid, this method (add_cell) checks if a cell already exists in the grid before to add it.

struct Cell {
    // A simplified version with only one coordinate
    position: i8,
}

struct Grid {
    // List of cells in the grid
    cells: Vec<Rc<Cell>>,
}

impl Grid {
    // Add a cell in to the grid
    pub fn add_cell(&mut self, cell: Cell) {
        let is_not_yet_in;
        {
            if self.cells.iter().find(|&c| c.position == cell.position).is_some() {
                is_not_yet_in = false;
            } else {
                is_not_yet_in = true;
            }
        }
        if is_not_yet_in {
            self.cells.push(Rc::new(cell).clone());
        }
    }
}

I put the fake scope, after is_not_yet_in declaration, in order to avoid compiling error on mutable/immutable borrowing of self.cells. Anyway I think this trick can be avoid using a different approach.

Upvotes: 0

Views: 2283

Answers (1)

Shepmaster
Shepmaster

Reputation: 430673

You should read over and commit to memory the methods of the Iterator trait. Specifically, you want any here. I also flipped the polarity on your variable name to match.

pub fn add_cell(&mut self, cell: Cell) {
    let is_present = self.cells.iter().any(|c| c.position == cell.position);
    if !is_present {
        self.cells.push(Rc::new(cell).clone());
    }
}

Additionally, Rc::new(cell).clone() doesn't make any sense — you might as well shorten it to Rc::new(cell).

Upvotes: 5

Related Questions