Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Ockajak committed Jul 19, 2024
1 parent 7aa3b25 commit fa0ec60
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 68 deletions.
4 changes: 2 additions & 2 deletions src/extensions/collectible.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1342,7 +1342,7 @@ where
return None;
}
current_slot = k;
let result = Some(collect_by_index(values, &combination[1..]));
let tuple = Some(collect_by_index(values, &combination[1..]));
while combination[current_slot] >= (size + current_slot - k) as i64 - 1 {
current_slot -= 1;
}
Expand All @@ -1351,7 +1351,7 @@ where
new_index += 1;
*index = new_index;
}
result
tuple
})
.collect()
}
Expand Down
48 changes: 39 additions & 9 deletions src/extensions/collections/linked_list.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::extensions::util::unfold::unfold;
use crate::extensions::*;
use std::cmp::Ordering;
use std::collections::{BTreeSet, HashMap, LinkedList};
use std::collections::{BTreeMap, BTreeSet, HashMap, LinkedList};
use std::fmt::Display;
use std::hash::Hash;

use crate::extensions::util::unfold::unfold;
use crate::extensions::*;
use std::iter;

impl<Item> Traversable<Item> for LinkedList<Item> {
#[inline]
Expand Down Expand Up @@ -354,7 +354,7 @@ impl<Item> Sequence<Item> for LinkedList<Item> {
fn map_while<B>(&self, predicate: impl FnMut(&Item) -> Option<B>) -> Self::This<B> {
self.iter().map_while(predicate).collect()
}

fn move_at(self, source_index: usize, target_index: usize) -> Self {
if source_index == target_index {
let size = self.len();
Expand All @@ -373,9 +373,9 @@ impl<Item> Sequence<Item> for LinkedList<Item> {
source_item = Some(value);
}
}
let result = if index == target_index { source_item.take() } else { iterator.next() };
let new_item = if index == target_index { source_item.take() } else { iterator.next() };
index += 1;
result
new_item
})
.collect()
} else {
Expand Down Expand Up @@ -409,6 +409,36 @@ impl<Item> Sequence<Item> for LinkedList<Item> {
self.iter().scan(init, function).collect()
}

#[inline]
fn substitute_at(self, index: usize, replacement: Item) -> Self
where
Self: IntoIterator<Item = Item> + FromIterator<Item>,
{
self.substitute_at_multi(index..(index + 1), iter::once(replacement))
}

fn substitute_at_multi(
self, indices: impl IntoIterator<Item = usize>, replacements: impl IntoIterator<Item = Item>,
) -> Self
where
Self: IntoIterator<Item = Item> + FromIterator<Item>,
{
let mut index_replacements: BTreeMap<usize, Item> = BTreeMap::from_iter(indices.into_iter().zip(replacements));
let mut index = 0_usize;
let result = self
.into_iter()
.map(|item| {
let new_item = index_replacements.remove(&index).unwrap_or(item);
index += 1;
new_item
})
.collect();
if let Some(unused_index) = index_replacements.keys().next() {
panic!(r#"index (is {unused_index:?}) should be < len (is {index:?})"#);
};
result
}

fn swap_at(self, source_index: usize, target_index: usize) -> Self {
if source_index == target_index {
let size = self.len();
Expand All @@ -424,7 +454,7 @@ impl<Item> Sequence<Item> for LinkedList<Item> {
let mut stored = LinkedList::<Item>::new();
let mut source_item = None;
unfold(|| {
let result = match index.cmp(&source) {
let new_item = match index.cmp(&source) {
Ordering::Less => iterator.next(),
Ordering::Equal => {
source_item = iterator.next();
Expand All @@ -446,7 +476,7 @@ impl<Item> Sequence<Item> for LinkedList<Item> {
}
};
index += 1;
result
new_item
})
.collect()
}
Expand Down
20 changes: 20 additions & 0 deletions src/extensions/collections/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,26 @@ impl<Item> Sequence<Item> for Vec<Item> {
result
}

#[inline]
fn substitute_at(mut self, index: usize, replacement: Item) -> Self
where
Self: IntoIterator<Item = Item> + FromIterator<Item>
{
self[index] = replacement;
self
}

#[inline]
fn substitute_at_multi(mut self, indices: impl IntoIterator<Item = usize>, replacements: impl IntoIterator<Item = Item>) -> Self
where
Self: IntoIterator<Item = Item> + FromIterator<Item>
{
for (index, replacement) in indices.into_iter().zip(replacements) {
self[index] = replacement;
}
self
}

#[inline]
fn swap_at(mut self, source_index: usize, target_index: usize) -> Self {
self.swap(source_index, target_index);
Expand Down
20 changes: 20 additions & 0 deletions src/extensions/collections/vec_deque.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,26 @@ impl<Item> Sequence<Item> for VecDeque<Item> {
self.iter().scan(init, function).collect()
}

#[inline]
fn substitute_at(mut self, index: usize, replacement: Item) -> Self
where
Self: IntoIterator<Item = Item> + FromIterator<Item>
{
self[index] = replacement;
self
}

#[inline]
fn substitute_at_multi(mut self, indices: impl IntoIterator<Item = usize>, replacements: impl IntoIterator<Item = Item>) -> Self
where
Self: IntoIterator<Item = Item> + FromIterator<Item>
{
for (index, replacement) in indices.into_iter().zip(replacements) {
self[index] = replacement;
}
self
}

#[inline]
fn swap_at(mut self, source_index: usize, target_index: usize) -> Self {
self.swap(source_index, target_index);
Expand Down
4 changes: 2 additions & 2 deletions src/extensions/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ pub(crate) fn repeat<'a, Item: Clone + 'a, Collection: FromIterator<Item>>(
if remaining == 0 {
return None;
}
let result = values.next().map(|&x| x.clone());
let new_item = values.next().map(|&x| x.clone());
remaining -= 1;
result
new_item
})
.collect()
}
74 changes: 19 additions & 55 deletions src/extensions/sequence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,6 @@ pub trait Sequence<Item> {
///
/// # let a_source = vec![1, 2, 3];
/// let a = vec![1, 2, 3];
/// let e = Vec::<i32>::new();
///
/// assert_eq!(a.delete_at(0), vec![2, 3]);
/// # let a = a_source.clone();
Expand All @@ -394,7 +393,6 @@ pub trait Sequence<Item> {
///
/// # let a_source = vec![1, 2, 3];
/// let a = vec![1, 2, 3];
/// let e = Vec::<i32>::new();
///
/// assert_eq!(a.delete_at_multi(vec![0, 2]), vec![2]);
/// # let a = a_source.clone();
Expand Down Expand Up @@ -716,13 +714,13 @@ pub trait Sequence<Item> {
let mut iterator_right = elements.into_iter();
let mut left = true;
unfold(|| {
let result = if left {
let new_item = if left {
iterator_left.next().or_else(|| iterator_right.next())
} else {
iterator_right.next().or_else(|| iterator_left.next())
};
left = !left;
result
new_item
})
.collect()
}
Expand Down Expand Up @@ -1015,9 +1013,9 @@ pub trait Sequence<Item> {
let original_start = size - iterator.len();
let mut index = 0_usize;
unfold(|| {
let result = if index < original_start { Some(to_element(index)) } else { iterator.next() };
let new_item = if index < original_start { Some(to_element(index)) } else { iterator.next() };
index += 1;
result
new_item
})
.collect()
}
Expand Down Expand Up @@ -1067,9 +1065,9 @@ pub trait Sequence<Item> {
let mut iterator = self.into_iter();
let mut index = 0_usize;
unfold(|| {
let result = iterator.next().or_else(|| if index < size { Some(to_element(index)) } else { None });
let new_item = iterator.next().or_else(|| if index < size { Some(to_element(index)) } else { None });
index += 1;
result
new_item
})
.collect()
}
Expand Down Expand Up @@ -1720,21 +1718,10 @@ pub trait Sequence<Item> {
///
/// # let a_source = vec![1, 2, 3];
/// let a = vec![1, 2, 3];
/// let e = Vec::<i32>::new();
///
/// assert_eq!(a.substitute_at(1, 4), vec![1, 4, 3]);
///
/// # let a = a_source.clone();
/// assert_eq!(a.substitute_at(3, 5), vec![1, 2, 3]);
/// assert_eq!(e.substitute_at(0, 1), vec![]);
/// ```
#[inline]
fn substitute_at(self, index: usize, replacement: Item) -> Self
where
Self: IntoIterator<Item = Item> + FromIterator<Item>,
{
self.substitute_at_multi(index..(index + 1), iter::once(replacement))
}
fn substitute_at(self, index: usize, replacement: Item) -> Self;

/// Creates a new sequence by replacing all elements at specified indices in this sequence
/// by elements from another collection.
Expand All @@ -1752,39 +1739,16 @@ pub trait Sequence<Item> {
///
/// # let a_source = vec![1, 2, 3];
/// let a = vec![1, 2, 3];
/// let e = Vec::<i32>::new();
///
/// assert_eq!(a.substitute_at_multi(vec![0, 2], vec![4, 5]), vec![4, 2, 5]);
/// # let a = a_source.clone();
/// assert_eq!(a.substitute_at_multi(vec![1, 3], vec![4, 5]), vec![1, 4, 3]);
/// # let a = a_source.clone();
/// assert_eq!(a.substitute_at_multi(vec![0, 2], vec![4]), vec![4, 2, 3]);
/// # let a = a_source.clone();
/// assert_eq!(a.substitute_at_multi(vec![0, 2], vec![4, 5, 6]), vec![4, 2, 5]);
///
/// # let a = a_source.clone();
/// assert_eq!(a.substitute_at_multi(vec![3, 4], vec![4, 5]), vec![1, 2, 3]);
/// assert_eq!(e.substitute_at_multi(vec![0], vec![1]), vec![]);
/// ```
fn substitute_at_multi(
self, indices: impl IntoIterator<Item = usize>, replacements: impl IntoIterator<Item = Item>,
) -> Self
where
Self: IntoIterator<Item = Item> + FromIterator<Item>,
{
let positions: BTreeSet<usize> = BTreeSet::from_iter(indices);
let mut iterator = self.into_iter();
let mut replacement_items = replacements.into_iter();
let mut index = 0_usize;
unfold(|| {
iterator.next().map(|item| {
let result = if positions.contains(&index) { replacement_items.next().unwrap_or(item) } else { item };
index += 1;
result
})
})
.collect()
}
) -> Self;

/// Creates a new sequence by swapping an elements at specified indices
/// in this sequence.
Expand Down Expand Up @@ -2099,7 +2063,7 @@ pub trait Sequence<Item> {
/// assert_eq!(a.windowed_circular(2, 1), vec![vec![1, 2], vec![2, 3], vec![3, 1]]);
/// # let a = a_source.clone();
/// assert_eq!(a.windowed_circular(2, 2), vec![vec![1, 2], vec![3, 4], vec![5, 1]]);
///
///
/// assert_eq!(e.windowed_circular(1, 1), Vec::<Vec<i32>>::new());
/// ```
fn windowed_circular(&self, size: usize, step: usize) -> Vec<Self>
Expand Down Expand Up @@ -2215,15 +2179,15 @@ pub(crate) fn cartesian_product<'a, Item: Clone + 'a, Collection: FromIterator<I
return None;
}
current_slot = k;
let result = Some(collect_by_index(&values, &product[1..]));
let tuple = Some(collect_by_index(&values, &product[1..]));
while product[current_slot] >= (size - 1) as i64 {
current_slot -= 1;
}
product[current_slot] += 1;
for index in &mut product[(current_slot + 1)..=k] {
*index = 0;
}
result
tuple
})
.collect()
}
Expand Down Expand Up @@ -2276,15 +2240,15 @@ pub(crate) fn combinations_multi<'a, Item: Clone + 'a, Collection: FromIterator<
return None;
}
current_slot = k;
let result = Some(collect_by_index(&values, &multi_combination[1..]));
let tuple = Some(collect_by_index(&values, &multi_combination[1..]));
while multi_combination[current_slot] >= (size - 1) as i64 {
current_slot -= 1;
}
let new_index = multi_combination[current_slot] + 1;
for index in &mut multi_combination[current_slot..=k] {
*index = new_index;
}
result
tuple
})
.collect()
}
Expand All @@ -2303,7 +2267,7 @@ pub(crate) fn variations<'a, Item: Clone + 'a, Collection: FromIterator<Item> +
return None;
}
current_slot = k;
let result = Some(collect_by_index(&values, &variation[1..]));
let tuple = Some(collect_by_index(&values, &variation[1..]));
while current_slot > 0 && ((variation[current_slot] + 1)..(size as i64)).all(|x| used_indices[x as usize]) {
used_indices[variation[current_slot] as usize] = false;
current_slot -= 1;
Expand All @@ -2319,7 +2283,7 @@ pub(crate) fn variations<'a, Item: Clone + 'a, Collection: FromIterator<Item> +
*index = new_index;
}
}
result
tuple
})
.collect()
}
Expand All @@ -2334,11 +2298,11 @@ pub(crate) fn windowed<'a, Item: Clone + 'a, Collection: FromIterator<Item>>(
.flat_map(|item| {
window.push_back(item.clone());
if window.len() >= size {
let result = Some(Collection::from_iter(window.clone()));
let tuple = Some(Collection::from_iter(window.clone()));
for _ in 0..step {
let _unused = window.pop_front();
}
result
tuple
} else {
None
}
Expand Down Expand Up @@ -2366,11 +2330,11 @@ pub(crate) fn windowed_circular<'a, Item: Clone + 'a, Collection: FromIterator<I
return None;
}
}
let result = Some(Collection::from_iter(window.clone()));
let tuple = Some(Collection::from_iter(window.clone()));
for _ in 0..step {
let _unused = window.pop_front();
}
result
tuple
})
.collect()
}

0 comments on commit fa0ec60

Please sign in to comment.