From 43511b4f1b24571a9cf75b358f8ad702240b53b5 Mon Sep 17 00:00:00 2001 From: Martin Ockajak Date: Fri, 19 Jul 2024 04:57:37 +0200 Subject: [PATCH] . --- src/extensions/collections/linked_list.rs | 25 ++++++++++++++++++- src/extensions/collections/vec.rs | 29 ++++++++++++++++++++++ src/extensions/collections/vec_deque.rs | 30 ++++++++++++++++++++++- src/extensions/sequence.rs | 20 ++------------- 4 files changed, 84 insertions(+), 20 deletions(-) diff --git a/src/extensions/collections/linked_list.rs b/src/extensions/collections/linked_list.rs index 68c2b0a..092eb2d 100644 --- a/src/extensions/collections/linked_list.rs +++ b/src/extensions/collections/linked_list.rs @@ -1,5 +1,5 @@ use std::cmp::Ordering; -use std::collections::{HashMap, LinkedList}; +use std::collections::{BTreeSet, HashMap, LinkedList}; use std::fmt::Display; use std::hash::Hash; @@ -322,6 +322,29 @@ impl Sequence for LinkedList { combinations_multi(self.iter(), k) } + #[inline] + fn delete_at(self, index: usize) -> Self + { + let size = self.len(); + if index >= size { + panic!(r#"removal index (is {index:?}) should be < len (is {size:?})"#) + } + self.into_iter().enumerate().filter_map(|(i, x)| if i == index { None } else { Some(x) }).collect() + } + + #[inline] + fn delete_at_multi(self, indices: impl IntoIterator) -> Self + { + let size = self.len(); + let positions: BTreeSet = BTreeSet::from_iter(indices.into_iter().map(|index| { + if index >= size { + panic!(r#"removal index (is {index:?}) should be < len (is {size:?})"#) + }; + index + })); + self.into_iter().enumerate().filter_map(|(i, x)| if positions.contains(&i) { None } else { Some(x) }).collect() + } + #[inline] fn init(mut self) -> Self { let _unused = self.pop_back(); diff --git a/src/extensions/collections/vec.rs b/src/extensions/collections/vec.rs index 52f8e11..c413152 100644 --- a/src/extensions/collections/vec.rs +++ b/src/extensions/collections/vec.rs @@ -238,7 +238,11 @@ impl Collectible for Vec { Item: PartialEq, Self: IntoIterator + FromIterator, { + let size = self.len(); if let Some(index) = self.iter().position(|x| x == element) { + if index >= size { + panic!(r#"replacement index (is {index:?}) should be < len (is {size:?})"#) + } self[index] = replacement; } self @@ -360,6 +364,31 @@ impl Sequence for Vec { combinations_multi(self.iter(), k) } + #[inline] + fn delete_at(mut self, index: usize) -> Self + { + let _unused = self.remove(index); + self + } + + fn delete_at_multi(mut self, indices: impl IntoIterator) -> Self + { + let mut deleted_indices = Vec::::from_iter(indices); + let mut last = usize::MAX; + let size = self.len(); + deleted_indices.sort_unstable(); + for index in deleted_indices.into_iter().rev() { + if index >= size { + panic!(r#"removal index (is {index:?}) should be < len (is {size:?})"#) + } + if index != last { + let _unused = self.remove(index); + last = index; + } + } + self + } + #[inline] fn init(mut self) -> Self { if !self.is_empty() { diff --git a/src/extensions/collections/vec_deque.rs b/src/extensions/collections/vec_deque.rs index eb5043a..a0fce6b 100644 --- a/src/extensions/collections/vec_deque.rs +++ b/src/extensions/collections/vec_deque.rs @@ -232,13 +232,16 @@ impl Collectible for VecDeque { powerset(self.iter()) } - #[inline] fn substitute(mut self, element: &Item, replacement: Item) -> Self where Item: PartialEq, Self: IntoIterator + FromIterator, { + let size = self.len(); if let Some(index) = self.iter().position(|x| x == element) { + if index >= size { + panic!(r#"replacement index (is {index:?}) should be < len (is {size:?})"#) + } self[index] = replacement; } self @@ -376,6 +379,31 @@ impl Sequence for VecDeque { combinations_multi(self.iter(), k) } + #[inline] + fn delete_at(mut self, index: usize) -> Self + { + let _unused = self.remove(index); + self + } + + fn delete_at_multi(mut self, indices: impl IntoIterator) -> Self + { + let mut deleted_indices = Vec::::from_iter(indices); + let mut last = usize::MAX; + let size = self.len(); + deleted_indices.sort_unstable(); + for index in deleted_indices.into_iter().rev() { + if index >= size { + panic!(r#"removal index (is {index:?}) should be < len (is {size:?})"#) + } + if index != last { + let _unused = self.remove(index); + last = index; + } + } + self + } + #[inline] fn init(mut self) -> Self { if !self.is_empty() { diff --git a/src/extensions/sequence.rs b/src/extensions/sequence.rs index d60b2fa..1a6487a 100644 --- a/src/extensions/sequence.rs +++ b/src/extensions/sequence.rs @@ -374,18 +374,8 @@ pub trait Sequence { /// assert_eq!(a.delete_at(1), vec![1, 3]); /// # let a = a_source.clone(); /// assert_eq!(a.delete_at(2), vec![1, 2]); - /// assert_eq!(e.delete_at(0), vec![]); - /// - /// # let a = a_source.clone(); - /// assert_eq!(a.delete_at(3), vec![1, 2, 3]); /// ``` - #[inline] - fn delete_at(self, index: usize) -> Self - where - Self: IntoIterator + FromIterator, - { - self.into_iter().enumerate().filter_map(|(i, x)| if i == index { None } else { Some(x) }).collect() - } + fn delete_at(self, index: usize) -> Self; /// Creates a new sequence by omitting elements at specified indices /// in this sequence. @@ -403,13 +393,7 @@ pub trait Sequence { /// /// assert_eq!(a.delete_at_multi(vec![0, 2]), vec![2]); /// # let a = a_source.clone(); - /// assert_eq!(a.delete_at_multi(vec![1, 3]), vec![1, 3]); - /// # let a = a_source.clone(); - /// assert_eq!(a.delete_at_multi(vec![0, 1, 2, 3]), vec![]); - /// - /// assert_eq!(e.delete_at_multi(vec![1, 2]), vec![]); - /// # let a = a_source.clone(); - /// assert_eq!(a.delete_at_multi(vec![3, 4]), vec![1, 2, 3]); + /// assert_eq!(a.delete_at_multi(vec![0, 1, 2]), vec![]); /// ``` #[inline] fn delete_at_multi(self, indices: impl IntoIterator) -> Self