Convert vec::windowed to an external iterator, and add an n-at-a-time chunk iterator.
This commit is contained in:
@@ -452,27 +452,46 @@ pub fn each_permutation<T:Copy>(values: &[T], fun: &fn(perm : &[T]) -> bool) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// An iterator over the (overlapping) slices of length `size` within
|
||||||
* Iterate over all contiguous windows of length `n` of the vector `v`.
|
/// a vector.
|
||||||
*
|
pub struct VecWindowIter<'self, T> {
|
||||||
* # Example
|
priv v: &'self [T],
|
||||||
*
|
priv size: uint
|
||||||
* Print the adjacent pairs of a vector (i.e. `[1,2]`, `[2,3]`, `[3,4]`)
|
}
|
||||||
*
|
|
||||||
* ~~~ {.rust}
|
impl<'self, T> Iterator<&'self [T]> for VecWindowIter<'self, T> {
|
||||||
* for windowed(2, &[1,2,3,4]) |v| {
|
fn next(&mut self) -> Option<&'self [T]> {
|
||||||
* io::println(fmt!("%?", v));
|
if self.size > self.v.len() {
|
||||||
* }
|
None
|
||||||
* ~~~
|
} else {
|
||||||
*
|
let ret = Some(self.v.slice(0, self.size));
|
||||||
*/
|
self.v = self.v.slice(1, self.v.len());
|
||||||
pub fn windowed<'r, T>(n: uint, v: &'r [T], it: &fn(&'r [T]) -> bool) -> bool {
|
ret
|
||||||
assert!(1u <= n);
|
}
|
||||||
if n > v.len() { return true; }
|
}
|
||||||
for uint::range(0, v.len() - n + 1) |i| {
|
}
|
||||||
if !it(v.slice(i, i + n)) { return false; }
|
|
||||||
|
/// An iterator over a vector in (non-overlapping) chunks (`size`
|
||||||
|
/// elements at a time).
|
||||||
|
pub struct VecChunkIter<'self, T> {
|
||||||
|
priv v: &'self [T],
|
||||||
|
priv size: uint
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'self, T> Iterator<&'self [T]> for VecChunkIter<'self, T> {
|
||||||
|
fn next(&mut self) -> Option<&'self [T]> {
|
||||||
|
if self.size == 0 {
|
||||||
|
None
|
||||||
|
} else if self.size >= self.v.len() {
|
||||||
|
// finished
|
||||||
|
self.size = 0;
|
||||||
|
Some(self.v)
|
||||||
|
} else {
|
||||||
|
let ret = Some(self.v.slice(0, self.size));
|
||||||
|
self.v = self.v.slice(self.size, self.v.len());
|
||||||
|
ret
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -728,6 +747,9 @@ pub trait ImmutableVector<'self, T> {
|
|||||||
fn rsplit_iter(self, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T>;
|
fn rsplit_iter(self, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T>;
|
||||||
fn rsplitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T>;
|
fn rsplitn_iter(self, n: uint, pred: &'self fn(&T) -> bool) -> VecRSplitIterator<'self, T>;
|
||||||
|
|
||||||
|
fn window_iter(self, size: uint) -> VecWindowIter<'self, T>;
|
||||||
|
fn chunk_iter(self, size: uint) -> VecChunkIter<'self, T>;
|
||||||
|
|
||||||
fn head(&self) -> &'self T;
|
fn head(&self) -> &'self T;
|
||||||
fn head_opt(&self) -> Option<&'self T>;
|
fn head_opt(&self) -> Option<&'self T>;
|
||||||
fn tail(&self) -> &'self [T];
|
fn tail(&self) -> &'self [T];
|
||||||
@@ -817,6 +839,62 @@ impl<'self,T> ImmutableVector<'self, T> for &'self [T] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an iterator over all contiguous windows of length
|
||||||
|
* `size`. The windows overlap. If the vector is shorter than
|
||||||
|
* `size`, the iterator returns no values.
|
||||||
|
*
|
||||||
|
* # Failure
|
||||||
|
*
|
||||||
|
* Fails if `size` is 0.
|
||||||
|
*
|
||||||
|
* # Example
|
||||||
|
*
|
||||||
|
* Print the adjacent pairs of a vector (i.e. `[1,2]`, `[2,3]`,
|
||||||
|
* `[3,4]`):
|
||||||
|
*
|
||||||
|
* ~~~ {.rust}
|
||||||
|
* let v = &[1,2,3,4];
|
||||||
|
* for v.window_iter().advance |win| {
|
||||||
|
* io::println(fmt!("%?", win));
|
||||||
|
* }
|
||||||
|
* ~~~
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
fn window_iter(self, size: uint) -> VecWindowIter<'self, T> {
|
||||||
|
assert!(size != 0);
|
||||||
|
VecWindowIter { v: self, size: size }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Returns an iterator over `size` elements of the vector at a
|
||||||
|
* time. The chunks do not overlap. If `size` does not divide the
|
||||||
|
* length of the vector, then the last chunk will not have length
|
||||||
|
* `size`.
|
||||||
|
*
|
||||||
|
* # Failure
|
||||||
|
*
|
||||||
|
* Fails if `size` is 0.
|
||||||
|
*
|
||||||
|
* # Example
|
||||||
|
*
|
||||||
|
* Print the vector two elements at a time (i.e. `[1,2]`,
|
||||||
|
* `[3,4]`, `[5]`):
|
||||||
|
*
|
||||||
|
* ~~~ {.rust}
|
||||||
|
* let v = &[1,2,3,4,5];
|
||||||
|
* for v.chunk_iter().advance |win| {
|
||||||
|
* io::println(fmt!("%?", win));
|
||||||
|
* }
|
||||||
|
* ~~~
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
fn chunk_iter(self, size: uint) -> VecChunkIter<'self, T> {
|
||||||
|
assert!(size != 0);
|
||||||
|
VecChunkIter { v: self, size: size }
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the first element of a vector, failing if the vector is empty.
|
/// Returns the first element of a vector, failing if the vector is empty.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn head(&self) -> &'self T {
|
fn head(&self) -> &'self T {
|
||||||
@@ -2663,31 +2741,6 @@ mod tests {
|
|||||||
assert_eq!([&[1], &[2], &[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
|
assert_eq!([&[1], &[2], &[3]].connect_vec(&0), ~[1, 0, 2, 0, 3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_windowed () {
|
|
||||||
fn t(n: uint, expected: &[&[int]]) {
|
|
||||||
let mut i = 0;
|
|
||||||
for windowed(n, [1,2,3,4,5,6]) |v| {
|
|
||||||
assert_eq!(v, expected[i]);
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check that we actually iterated the right number of times
|
|
||||||
assert_eq!(i, expected.len());
|
|
||||||
}
|
|
||||||
t(3, &[&[1,2,3],&[2,3,4],&[3,4,5],&[4,5,6]]);
|
|
||||||
t(4, &[&[1,2,3,4],&[2,3,4,5],&[3,4,5,6]]);
|
|
||||||
t(7, &[]);
|
|
||||||
t(8, &[]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_fail]
|
|
||||||
#[ignore(cfg(windows))]
|
|
||||||
fn test_windowed_() {
|
|
||||||
for windowed (0u, [1u,2u,3u,4u,5u,6u]) |_v| {}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_unshift() {
|
fn test_unshift() {
|
||||||
let mut x = ~[1, 2, 3];
|
let mut x = ~[1, 2, 3];
|
||||||
@@ -3035,6 +3088,40 @@ mod tests {
|
|||||||
assert_eq!(xs.rsplitn_iter(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
|
assert_eq!(xs.rsplitn_iter(1, |x| *x == 5).collect::<~[&[int]]>(), ~[&[]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_window_iterator() {
|
||||||
|
let v = &[1i,2,3,4];
|
||||||
|
|
||||||
|
assert_eq!(v.window_iter(2).collect::<~[&[int]]>(), ~[&[1,2], &[2,3], &[3,4]]);
|
||||||
|
assert_eq!(v.window_iter(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[2,3,4]]);
|
||||||
|
assert!(v.window_iter(6).next().is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_fail]
|
||||||
|
#[ignore(cfg(windows))]
|
||||||
|
fn test_window_iterator_0() {
|
||||||
|
let v = &[1i,2,3,4];
|
||||||
|
let _it = v.window_iter(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_chunk_iterator() {
|
||||||
|
let v = &[1i,2,3,4,5];
|
||||||
|
|
||||||
|
assert_eq!(v.chunk_iter(2).collect::<~[&[int]]>(), ~[&[1i,2], &[3,4], &[5]]);
|
||||||
|
assert_eq!(v.chunk_iter(3).collect::<~[&[int]]>(), ~[&[1i,2,3], &[4,5]]);
|
||||||
|
assert_eq!(v.chunk_iter(6).collect::<~[&[int]]>(), ~[&[1i,2,3,4,5]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_fail]
|
||||||
|
#[ignore(cfg(windows))]
|
||||||
|
fn test_chunk_iterator_0() {
|
||||||
|
let v = &[1i,2,3,4];
|
||||||
|
let _it = v.chunk_iter(0);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_move_from() {
|
fn test_move_from() {
|
||||||
let mut a = [1,2,3,4,5];
|
let mut a = [1,2,3,4,5];
|
||||||
|
|||||||
Reference in New Issue
Block a user