@@ -48,6 +48,89 @@ impl Slice {
48
48
pub fn step_by ( self , step : Ixs ) -> Self {
49
49
Slice { step, ..self }
50
50
}
51
+
52
+ /// Returns the `n`th index in this slice.
53
+ ///
54
+ /// The `n` argument starts from zero, so `nth(0)` is the first index. If
55
+ /// `n` is greater than or equal to the length of the slice, then the
56
+ /// return value is `None`.
57
+ ///
58
+ /// # Examples
59
+ ///
60
+ /// ```
61
+ /// use ndarray::Slice;
62
+ ///
63
+ /// // indices 0, 1, 2, 3, 4
64
+ /// assert_eq!(Slice::new(0, Some(5), 1).nth(2), Some(2));
65
+ ///
66
+ /// // indices 1, 3
67
+ /// assert_eq!(Slice::new(1, Some(5), 2).nth(1), Some(3));
68
+ ///
69
+ /// // indices 1, -1, -3
70
+ /// assert_eq!(Slice::new(1, Some(-4), -2).nth(2), Some(-3));
71
+ ///
72
+ /// // indices 1, 3, 5, ...
73
+ /// assert_eq!(Slice::new(1, None, 2).nth(2), Some(5));
74
+ ///
75
+ /// // indices 3, 3, 3, ...
76
+ /// assert_eq!(Slice::new(3, Some(5), 0).nth(1000), Some(3));
77
+ ///
78
+ /// // indices 1, 3
79
+ /// assert_eq!(Slice::new(1, Some(5), 2).nth(2), None);
80
+ /// ```
81
+ pub fn nth ( & self , n : usize ) -> Option < isize > {
82
+ let nth = self . start + self . step * n as isize ;
83
+ if let Some ( end) = self . end {
84
+ if self . step == 0 || ( self . step > 0 && nth < end) || ( self . step < 0 && nth > end) {
85
+ Some ( nth)
86
+ } else {
87
+ None
88
+ }
89
+ } else {
90
+ Some ( nth)
91
+ }
92
+ }
93
+
94
+ /// Returns the number of indices when iterating over this slice.
95
+ ///
96
+ /// The return value is `None` if `self.end` is `None` or `self.step` is `0`.
97
+ ///
98
+ /// # Examples
99
+ ///
100
+ /// ```
101
+ /// use ndarray::Slice;
102
+ ///
103
+ /// // indices 0, 1, 2, 3, 4
104
+ /// assert_eq!(Slice::new(0, Some(5), 1).len(), Some(5));
105
+ ///
106
+ /// // indices 1, 3
107
+ /// assert_eq!(Slice::new(1, Some(5), 2).len(), Some(2));
108
+ ///
109
+ /// // indices 1, 3, 5
110
+ /// assert_eq!(Slice::new(1, Some(6), 2).len(), Some(3));
111
+ ///
112
+ /// // indices 1, -1
113
+ /// assert_eq!(Slice::new(1, Some(-3), -2).len(), Some(2));
114
+ ///
115
+ /// // indices 1, -1, -3
116
+ /// assert_eq!(Slice::new(1, Some(-4), -2).len(), Some(3));
117
+ ///
118
+ /// // indices 1, 3, 5, ... (self.end is None)
119
+ /// assert_eq!(Slice::new(1, None, 2).len(), None);
120
+ ///
121
+ /// // indices 3, 3, 3, ... (infinitely many)
122
+ /// assert_eq!(Slice::new(3, Some(5), 0).len(), None);
123
+ /// ```
124
+ pub fn len ( & self ) -> Option < usize > {
125
+ if self . step != 0 {
126
+ self . end . map ( |end| {
127
+ let delta = end - self . start ;
128
+ ( delta / self . step + if delta % self . step == 0 { 0 } else { 1 } ) as usize
129
+ } )
130
+ } else {
131
+ None
132
+ }
133
+ }
51
134
}
52
135
53
136
impl From < Range < Ixs > > for Slice {
0 commit comments