Skip to content

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

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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