【问题标题】:Read lines in pairs from stdin in rust从 rust 中的标准输入成对读取行
【发布时间】:2021-03-24 17:40:47
【问题描述】:

我的输入数据结构如下:

label_1
value_1
label_2
value_2
...

我的最终目标是将这些数据读入HashMap

我目前的工作方法是将偶数和奇数行放在两个单独的向量中,然后从两个向量中读取以添加到 Hashmap。

use std::io;
use std::io::prelude::*;
use std::collections::HashMap;

fn main() {
    
    let mut labels: Vec<String> = Vec::new();
    let mut values: Vec<String> = Vec::new();
     
    let stdin = io::stdin();

    /* Read lines piped from stdin*/
    for (i, line) in stdin.lock().lines().enumerate() {
    
        if i % 2 == 0 {
            /* store labels (even lines) in labels vector */
            labels.push(line.unwrap());

        } else {
            /* Store values (odd lines) in values vector */
            values.push(line.unwrap());
        }
    }

    println!("number of labels: {}", labels.len());
    println!("number of values: {}", values.len());
    


    /* Zip labels and values into one iterator */
    let double_iter = labels.iter().zip(values.iter());

    /* insert (label: value) pairs into hashmap */
    let mut records: HashMap<&String, &String> = HashMap::new();
    for (label, value) in double_iter {
        records.insert(label, value);
    }
}

我想问一下如何在不通过向量的中间步骤的情况下实现这个结果?

【问题讨论】:

    标签: rust stdin


    【解决方案1】:

    你可以使用itertools crate 中的.tuples()

    use itertools::Itertools;
    use std::io::{stdin, BufRead};
    
    fn main() {
        for (label, value) in stdin().lock().lines().tuples() {
            println!("{}: {}", label.unwrap(), value.unwrap());
        }
    }
    

    另见:

    • This answer on “是否有与 slice::chunks/windows 等效的迭代器来循环对、三元组等?”

    【讨论】:

    • 请注意,与next answer不同,当存在未配对的线路时,此操作会静默失败。
    【解决方案2】:

    您可以使用 .next() 手动推进迭代器

    use std::io;
    use std::io::prelude::*;
    use std::collections::HashMap;
    
    fn main() {
        let stdin = io::stdin();
        let mut lines = stdin.lock().lines();
        let mut records = HashMap::new();
    
        while let Some(label) = lines.next() {
            let value = lines.next().expect("No value for label");
            records.insert(label.unwrap(), value.unwrap());
        }
    }
    

    Playground

    【讨论】:

      【解决方案3】:

      怎么样:

      fn main() {
          let lines = vec![1,2,3,4,5,6];
          let mut records = std::collections::HashMap::new();
      
          for i in (0..lines.len()).step_by(2) {
              // make sure the `i+1` is existed
              println!("{}{}", lines[i], lines[i + 1]);
              records.insert(lines[i], lines[i + 1]);
          }
      }
      

      【讨论】:

      • 如果你已经有了向量,那么你也可以使用.chunks(2)来代替。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-30
      • 2012-02-17
      • 2011-10-21
      • 2018-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多