首页 > 解决方案 > 循环文件,索引字符

问题描述

我是 Rust 的新手。
我想得到a之后ab之后a等的概率......
我试图得到一个HashMap<&str, HashMap<&str, u128>>喜欢:

{
  a : {
    a: 0,
    b: 2,
    c: 1,
    ...
  },
  b: {
    ...
}

这是我的代码:

use std::collections::HashMap;
use std::fs::File;
use std::io::BufRead;
use std::{fs, io};

fn main() {
    let mut letters_repatition: HashMap<&str, HashMap<&str, u128>> = HashMap::new();

    // get all file, and loop into it
    if let Ok(read_dir) = fs::read_dir("resources/") {
        if let Ok(files_paths) = read_dir
            .map(|res| res.map(|e| e.path()))
            .collect::<Result<Vec<_>, io::Error>>()
        {
            for path in files_paths {
                // get content file
                if let Ok(file) = File::open(path) {
                    let buf_lines = io::BufReader::new(file).lines();
                    // loop throught file's lines
                    for buf_line in buf_lines {
                        if let Ok(mut line) = buf_line {
                            if line.len() > 0 {
                                line = format!(" {:} ", line);
                                // loop on file lines
                                for i in 0..(line.len() - 2) {
                                    // get index letter
                                    if let Some(current_letter) = line.get(i..i + 1) {
                                        // get index + 1 letter
                                        if let Some(next_letter) = line.get(i + 1..i + 2) {
                                            // findOrCreate letter
                                            let sub_letters_repatition = letters_repatition
                                                .entry(current_letter)
                                                .or_insert(HashMap::new());

                                            // findOrCreate sub array entry
                                            let letter_count = sub_letters_repatition
                                                .entry(next_letter)
                                                .or_insert(0);

                                            // increment next letter counter
                                            *letter_count += 1;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

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

我收到了这个错误:

$ cargo run
   Compiling book_parser v0.1.0 (~\rust-project)
error[E0597]: `line` does not live long enough
  --> src\main.rs:27:67
   |
27 |                                     if let Some(current_letter) = line.get(i..i + 1) {
   |                                                                   ^^^^ borrowed value does not live long enough
...
46 |                         }
   |                         - `line` dropped here while still borrowed
...
53 |     println!("{:?}", letters_repatition);
   |                      ------------------ borrow later used here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0597`.
error: could not compile `book_parser`

如何使用提取字符串的字母作为我的键HashMap

标签: rust

解决方案


感谢@tadman 和@Jmb

我已经设法完成我的脚本:

use std::collections::HashMap;
use std::fs::File;
use std::io::BufRead;
use std::{fs, io};

fn main() {
    let mut letters_repatition: HashMap<char, HashMap<char, u64>> = HashMap::new();

    // get all file, and loop into it
    if let Ok(read_dir) = fs::read_dir("resources/") {
        if let Ok(files_paths) = read_dir
            .map(|res| res.map(|e| e.path()))
            .collect::<Result<Vec<_>, io::Error>>()
        {
            for path in files_paths {
                // get content file
                if let Ok(file) = File::open(path) {
                    let buf_lines = io::BufReader::new(file).lines();
                    // loop throught file's lines
                    for buf_line in buf_lines {
                        if let Ok(mut line) = buf_line {
                            if line.len() > 0 {
                                line = format!("{:} ", line);
                                let chars = line.chars();
                                let mut previous_char = ' ';
                                // loop on file chars
                                for current_char in chars {
                                    // findOrCreate letter
                                    let sub_letters_repatition = letters_repatition
                                        .entry(previous_char)
                                        .or_insert(HashMap::new());

                                    // findOrCreate sub array entry
                                    let letter_count = sub_letters_repatition
                                        .entry(current_char)
                                        .or_insert(0);

                                    // increment next letter counter
                                    *letter_count += 1;

                                    previous_char = current_char;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

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

推荐阅读