Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Collect iterators of length 2 into HashMap

Tags:

rust

I'm able to parse my input into effectively an Iterator<Iterator<i32>> where each inner iterator is length 2. The input looks like:

0: 3
1: 2
2: 4
4: 8
6: 5
8: 6
...

I can parse this with:

input.lines()
     .map(|line| line.split(": ")
                     .filter_map(|n| n.parse::<i32>().ok()))

The best way I came up with to put this into a HashMap is:

let mut tmp_map: HashMap<i32, i32> = HashMap::new();
for mut pair in input.lines()
                     .map(|line| line.split(": ")
                                     .filter_map(|n| n.parse::<i32>().ok()))
{
    tmp_map.insert(pair.next().unwrap(), pair.next().unwrap());
}

...which seems very unwieldy. Is there a way to collect this iterator into a HashMap?

Playground

like image 782
turbulencetoo Avatar asked Dec 13 '17 21:12

turbulencetoo


1 Answers

HashMap implements FromIterator<(K, V)>. Then it's just a matter of converting the text into an iterator of tuples. I like using Itertools::tuples:

const INPUT: &str = r#"0: 3
1: 2
2: 4
4: 8
6: 5
8: 6"#;

extern crate itertools;

use std::collections::HashMap;
use itertools::Itertools;

fn main() {
    let z: HashMap<u8, u8> = INPUT
        .lines()
        .flat_map(|l| l.split(":"))
        .flat_map(|n| n.trim().parse())
        .tuples()
        .collect();

    println!("{:?}", z);
}

See also:

  • How do I create a map from a list in a functional way?
like image 107
Shepmaster Avatar answered Nov 20 '22 12:11

Shepmaster