Skip to content

Commit 3c23086

Browse files
authored
Merge pull request #105 from OWissett/remove_except_issue
fixed issue #104
2 parents 91f959b + 49368e5 commit 3c23086

File tree

1 file changed

+26
-16
lines changed

1 file changed

+26
-16
lines changed

src/structs/pdb.rs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,10 @@ impl<'a> PDB {
697697

698698
/// Remove the Model specified.
699699
///
700+
/// ## Complexity
701+
/// * **Time**: amortized O(n) where n is the number of models, best case O(1) if model is the last one.
702+
/// * **Memory**: O(1)
703+
///
700704
/// ## Arguments
701705
/// * `index` - the index of the Model to remove
702706
///
@@ -709,43 +713,49 @@ impl<'a> PDB {
709713
/// Remove all Models except for models
710714
/// specified by idxs.
711715
///
716+
/// ## Complexity
717+
/// * **Time**: O(n) where n is the number of models.
718+
/// * **Memory**: O(k) where k is the number of models to keep.
719+
///
712720
/// ## Arguments
713721
/// * `idxs` - the indices of the Models to keep
714722
///
715723
/// ## Returns
716724
/// `None` if any of the indices are out of bounds.
717725
/// `Some(usize)` the number of models removed.
718726
pub fn remove_models_except(&mut self, idxs: &[usize]) -> Option<usize> {
727+
if self.models.is_empty() {
728+
#[cfg(debug_assertions)]
729+
eprint!("remove_models_except: no models to remove");
730+
return None;
731+
}
732+
719733
let start_count = self.model_count();
720-
let mut removed = 0_usize;
721734

722735
// bounds check the idxs
723736
if idxs.iter().max()? >= &start_count {
724737
return None;
725738
}
726739

727-
let idxs = (0..start_count).filter(|idx| !idxs.contains(idx));
728-
729-
for idx in idxs {
730-
self.models.swap(idx - removed, start_count - 1);
731-
removed += 1;
732-
}
740+
let retained: Vec<_> = self
741+
.models
742+
.drain(..)
743+
.enumerate()
744+
.filter(|(i, _)| idxs.contains(i))
745+
.map(|(_, m)| m)
746+
.collect();
733747

734-
self.models.truncate(start_count - removed);
748+
let removed = start_count - retained.len();
749+
self.models.clear();
750+
self.models.extend(retained);
735751

736752
Some(removed)
737753
}
738754

739755
/// Remove all Models except for the first one.
740756
///
741-
/// ## Panics
742-
/// Panics if there are no models.
743-
pub fn remove_all_models_except_first(&mut self) {
744-
if self.model_count() <= 1 {
745-
return;
746-
}
747-
748-
self.remove_models_except(&[0]);
757+
pub fn remove_all_models_except_first(&mut self) -> Option<usize> {
758+
self.remove_models_except(&[0])
749759
}
750760

751761
/// Remove the Model specified. It returns `true` if it found a matching Model and removed it.

0 commit comments

Comments
 (0)