I want to define a function that takes a parameter that can be iterated over without being consumed. The function should be able to take a Vec
but also other iterable objects. I am hung up on how to define a suitable generic parameter with a type constraint that will work. The purpose of the function is to get the maximum and minimum values from among all coordinates of a collection of points. (I store this in i64
because I will create other functions to handle u32
points, and they can get bigger than the largest i32
.) The collection is passed in as a slice, but how shall I represent the points? A Vec<i32>
will work as shown below, but I want anything that can produce a sequence of i32
. Whatever solution is offered, the function must still be callable on a slice of Vecs
(or pointers to Vecs
) and not consume them.
Here is my code using a slice of Vec
s:
use std::iter::{IntoIterator, Iterator};
use std::{i32, u32};
/// The observed range of values seen in a set of points whose coordinates are 32-bit integers (signed or unsigned).
///
/// From this information we can determine how to translate the coordinates so that their normalized range has a low of zero.
/// This permits us to use the fewest number of bits to represent them when constructing a Hilbert index.
pub struct IntegerDataRange {
pub low: i64,
pub high: i64,
}
impl IntegerDataRange {
pub fn from_i32(points: &[Vec<i32>]) -> Self {
let mut low = i32::MAX as i64;
let mut high = i32::MIN as i64;
for point in points.iter() {
for coordinate in point.iter().map(|c| *c as i64) {
if coordinate > high {
high = coordinate;
}
if coordinate < low {
low = coordinate;
}
}
}
IntegerDataRange {
low: low as i64,
high: high as i64,
}
}
}