@@ -2448,13 +2448,12 @@ pub trait Iterator {
2448
2448
/// ```
2449
2449
#[ inline]
2450
2450
#[ stable( feature = "iterator_fold_self" , since = "1.51.0" ) ]
2451
- fn reduce < F > ( mut self , f : F ) -> Option < Self :: Item >
2451
+ fn reduce < F > ( self , f : F ) -> Option < Self :: Item >
2452
2452
where
2453
2453
Self : Sized ,
2454
2454
F : FnMut ( Self :: Item , Self :: Item ) -> Self :: Item ,
2455
2455
{
2456
- let first = self . next ( ) ?;
2457
- Some ( self . fold ( first, f) )
2456
+ self . fold_first ( core:: convert:: identity, f)
2458
2457
}
2459
2458
2460
2459
/// Reduces the elements to a single one by repeatedly applying a reducing operation. If the
@@ -2537,6 +2536,53 @@ pub trait Iterator {
2537
2536
}
2538
2537
}
2539
2538
2539
+ /// Folds every element into an accumulator by applying an operation,
2540
+ /// returning the final result. The initial value is derived from the
2541
+ /// first element using the provided method.
2542
+ ///
2543
+ /// If the iterator is empty, returns [`None`]; otherwise, returns the
2544
+ /// result of the fold.
2545
+ ///
2546
+ /// The folding function is a closure with two arguments: an 'accumulator', and an element.
2547
+ /// For iterators with at least one element, this is the same as [`reduce()`]
2548
+ /// with the first element being fed into the init function
2549
+ ///
2550
+ /// [`reduce()`]: Iterator::reduce
2551
+ ///
2552
+ /// # Example
2553
+ ///
2554
+ /// ```
2555
+ /// #![feature(iterator_fold_first)]
2556
+ ///
2557
+ /// let min_max: (i32, i32) = [3, 1, 4, 1, 5, 9, 2]
2558
+ /// .into_iter()
2559
+ /// .fold_first(
2560
+ /// |first| (first, first),
2561
+ /// |(min, max), next| (i32::min(min, next), i32::max(max, next)),
2562
+ /// ).unwrap();
2563
+ /// assert_eq!(min_max, (1, 9));
2564
+ ///
2565
+ /// // Which is equivalent to doing it with `fold`:
2566
+ /// let folded: (i32, i32) = [3, 1, 4, 1, 5, 9, 2]
2567
+ /// .into_iter()
2568
+ /// .fold(
2569
+ /// (i32::MAX, i32::MIN),
2570
+ /// |(min, max), next| (i32::min(min, next), i32::max(max, next)),
2571
+ /// );
2572
+ /// assert_eq!(min_max, folded);
2573
+ /// ```
2574
+ #[ inline]
2575
+ #[ unstable( feature = "iterator_fold_first" , reason = "new API" , issue = "none" ) ]
2576
+ fn fold_first < B , F1 , FR > ( mut self , init : F1 , folding : FR ) -> Option < B >
2577
+ where
2578
+ Self : Sized ,
2579
+ F1 : FnOnce ( Self :: Item ) -> B ,
2580
+ FR : FnMut ( B , Self :: Item ) -> B ,
2581
+ {
2582
+ let first = init ( self . next ( ) ?) ;
2583
+ Some ( self . fold ( first, folding) )
2584
+ }
2585
+
2540
2586
/// Tests if every element of the iterator matches a predicate.
2541
2587
///
2542
2588
/// `all()` takes a closure that returns `true` or `false`. It applies
0 commit comments