Skip to content

A version of fold that works with mutable modifications of the accumulator, instead of returning a new one #1061

@TomFryersMidsummer

Description

@TomFryersMidsummer

Call it, say, fold_mut. Essentially, fold_mut is to FnMut(&mut B, T) as fold is to FnMut(B, T) -> B. This solves the annoying case of having to write code like the fast_union function below.

Here's an implementation and example use case:

trait Itertools_: Iterator {
    fn fold_mut<B>(self, init: B, mut f: impl FnMut(&mut B, Self::Item)) -> B
    where
        Self: Sized,
    {
        self.fold(init, |mut b, x| {
            f(&mut b, x);
            b
        })
    }
}

impl<T, I: Iterator<Item = T>> Itertools_ for I {}

type Set = std::collections::HashSet<u32>;

fn clean_union(sets: impl Iterator<Item = Set>) -> Set {
    sets.fold(Set::new(), |a, b| &a | &b)
}

fn fast_union(sets: impl Iterator<Item = Set>) -> Set {
    sets.fold(Set::new(), |mut a, b| {
        a.extend(b);
        a
    })
}

fn both_union(sets: impl Iterator<Item = Set>) -> Set {
    sets.fold_mut(Set::new(), Extend::extend)
}

This isn't tremendously simpler than the code it replaces; it's more of an Itertools::sorted than an Itertools::tuple_combinations.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions