Functional: Vec<(bool, T)> -> (bool, Vec<T>)

I have the following function:

fn foo(input: Vec<(bool, T)>) -> (bool, Vec<T>) {
  let mut b = false;
  let mut ans = vec![];
  for (ib, ix) in input.into_iter() {
    ib = ib || b;
    ans.push(ix);
  }
  (b, ans)
}

Is there a more functional way to write the above? My goal is to split the tuple, taking the OR of the bools, and just keeping the T's.

pub fn foo<T>(input: Vec<(bool, T)>) -> (bool, Vec<T>) {
    (input.iter().fold(false, |b, (ib, _)| *ib || b), input.into_iter().map(|(_, ix)| ix).collect())
}

*Praying* Gog save me from ever having to deal with code like this.

3 Likes

Few notes:

  • You don't need to call .into_iter() on input - for loop will do this for you.
  • Sometimes "functional way" and "most understandable way" are not the same thing. Advice: take the best of both worlds:
    fn foo(input: Vec<(bool, T)>) -> (bool, Vec<T>) {
      let mut bool_res = false;
      let out = input
        .into_iter()
        .map(|(b, val)| {
            bool_res = bool_res || b;
            val
        })
        .collect()
      (bool_res, out)
    }
    
5 Likes

unzip

1 Like