feat: implement IntoIterator for &Study and add iter() method
Enables idiomatic `for trial in &study` iteration over completed trials.
This commit is contained in:
@@ -1790,6 +1790,31 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> Study<V>
|
||||
where
|
||||
V: PartialOrd + Clone,
|
||||
{
|
||||
/// Returns an iterator over all completed trials.
|
||||
///
|
||||
/// This clones the internal trial list, so it is suitable for
|
||||
/// analysis and iteration but not for hot paths.
|
||||
pub fn iter(&self) -> std::vec::IntoIter<CompletedTrial<V>> {
|
||||
self.trials().into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> IntoIterator for &Study<V>
|
||||
where
|
||||
V: PartialOrd + Clone,
|
||||
{
|
||||
type Item = CompletedTrial<V>;
|
||||
type IntoIter = std::vec::IntoIter<CompletedTrial<V>>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<V> fmt::Display for Study<V>
|
||||
where
|
||||
V: PartialOrd + Clone + fmt::Display,
|
||||
|
||||
@@ -2097,3 +2097,47 @@ fn test_retries_with_zero_max_retries_same_as_optimize() {
|
||||
assert_eq!(call_count.get(), 5);
|
||||
assert_eq!(study.n_trials(), 5);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Tests: IntoIterator for &Study
|
||||
// =============================================================================
|
||||
|
||||
#[test]
|
||||
fn test_into_iterator_iterates_all_trials() {
|
||||
let study: Study<f64> = Study::with_sampler(Direction::Minimize, RandomSampler::with_seed(42));
|
||||
let x_param = FloatParam::new(0.0, 10.0);
|
||||
|
||||
for _ in 0..5 {
|
||||
let mut trial = study.create_trial();
|
||||
let x = x_param.suggest(&mut trial).unwrap();
|
||||
study.complete_trial(trial, x * x);
|
||||
}
|
||||
|
||||
let mut count = 0;
|
||||
for trial in &study {
|
||||
assert_eq!(trial.state, optimizer::TrialState::Complete);
|
||||
count += 1;
|
||||
}
|
||||
assert_eq!(count, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_iterator_empty_study() {
|
||||
let study: Study<f64> = Study::new(Direction::Minimize);
|
||||
|
||||
let count = (&study).into_iter().count();
|
||||
assert_eq!(count, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_into_iterator_preserves_insertion_order() {
|
||||
let study: Study<f64> = Study::new(Direction::Minimize);
|
||||
|
||||
for i in 0..3 {
|
||||
let trial = study.create_trial();
|
||||
study.complete_trial(trial, f64::from(i));
|
||||
}
|
||||
|
||||
let ids: Vec<u64> = (&study).into_iter().map(|t| t.id).collect();
|
||||
assert_eq!(ids, vec![0, 1, 2]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user