循环插入hashmap
Insert into hashmap in a loop
我正在打开一个 CSV 文件并使用 BufReader
读取它并将每一行拆分为一个向量。然后我尝试使用特定列作为键在 HashMap
中插入或更新计数。
let mut map: HashMap<&str, i32> = HashMap::new();
let reader = BufReader::new(input_file);
for line in reader.lines() {
let s = line.unwrap().to_string();
let tokens: Vec<&str> = s.split(&d).collect(); // <-- `s` does not live long enough
if tokens.len() > c {
println!("{}", tokens[c]);
let count = map.entry(tokens[c].to_string()).or_insert(0);
*count += 1;
}
}
编译器友好地告诉我 s
是短暂的。 Storing from inside a loop a borrowed value to container in outer scope? 建议 "owning" 字符串,所以我尝试更改
let count = map.entry(tokens[c]).or_insert(0);
到
let count = map.entry(tokens[c].to_string()).or_insert(0);
但我收到错误
expected `&str`, found struct `std::string::String`
help: consider borrowing here: `&tokens[c].to_string()`
当我在前面加上符号 (&
) 时,错误是
creates a temporary which is freed while still in use
note: consider using a `let` binding to create a longer lived
我对借用的Rust知识有一些不足。如何让散列映射拥有作为键传递的字符串?
最简单的方法是让您的地图拥有密钥。这意味着您必须将其类型从 HasMap<&str, i32>
(借用键)更改为 HashMap<String, i32>
。此时您可以调用 to_string
将您的令牌转换为拥有的字符串:
let mut map: HashMap<String, i32> = HashMap::new();
let reader = BufReader::new(input_file);
for line in reader.lines() {
let s = line.unwrap().to_string();
let tokens:Vec<&str> = s.split(&d).collect();
if tokens.len() > c {
println!("{}", tokens[c]);
let count = map.entry(tokens[c].to_string()).or_insert(0);
*count += 1;
}
}
但是请注意,这意味着 tokens[c]
将被复制,即使它已经存在于地图中。您可以通过首先尝试使用 get_mut
修改计数器来避免额外的重复,但是当密钥丢失时这需要两次查找:
let mut map: HashMap<String, i32> = HashMap::new();
let reader = BufReader::new(input_file);
for line in reader.lines() {
let s = line.unwrap().to_string();
let tokens:Vec<&str> = s.split(&d).collect();
if tokens.len() > c {
println!("{}", tokens[c]);
if let Some (count) = map.get_mut (tokens[c]) {
*count += 1;
} else {
map.insert (tokens[c].to_string(), 1);
}
}
}
我不知道有什么解决方案可以只在没有以前的条目时复制密钥,但仍然进行一次查找。
我正在打开一个 CSV 文件并使用 BufReader
读取它并将每一行拆分为一个向量。然后我尝试使用特定列作为键在 HashMap
中插入或更新计数。
let mut map: HashMap<&str, i32> = HashMap::new();
let reader = BufReader::new(input_file);
for line in reader.lines() {
let s = line.unwrap().to_string();
let tokens: Vec<&str> = s.split(&d).collect(); // <-- `s` does not live long enough
if tokens.len() > c {
println!("{}", tokens[c]);
let count = map.entry(tokens[c].to_string()).or_insert(0);
*count += 1;
}
}
编译器友好地告诉我 s
是短暂的。 Storing from inside a loop a borrowed value to container in outer scope? 建议 "owning" 字符串,所以我尝试更改
let count = map.entry(tokens[c]).or_insert(0);
到
let count = map.entry(tokens[c].to_string()).or_insert(0);
但我收到错误
expected `&str`, found struct `std::string::String`
help: consider borrowing here: `&tokens[c].to_string()`
当我在前面加上符号 (&
) 时,错误是
creates a temporary which is freed while still in use
note: consider using a `let` binding to create a longer lived
我对借用的Rust知识有一些不足。如何让散列映射拥有作为键传递的字符串?
最简单的方法是让您的地图拥有密钥。这意味着您必须将其类型从 HasMap<&str, i32>
(借用键)更改为 HashMap<String, i32>
。此时您可以调用 to_string
将您的令牌转换为拥有的字符串:
let mut map: HashMap<String, i32> = HashMap::new();
let reader = BufReader::new(input_file);
for line in reader.lines() {
let s = line.unwrap().to_string();
let tokens:Vec<&str> = s.split(&d).collect();
if tokens.len() > c {
println!("{}", tokens[c]);
let count = map.entry(tokens[c].to_string()).or_insert(0);
*count += 1;
}
}
但是请注意,这意味着 tokens[c]
将被复制,即使它已经存在于地图中。您可以通过首先尝试使用 get_mut
修改计数器来避免额外的重复,但是当密钥丢失时这需要两次查找:
let mut map: HashMap<String, i32> = HashMap::new();
let reader = BufReader::new(input_file);
for line in reader.lines() {
let s = line.unwrap().to_string();
let tokens:Vec<&str> = s.split(&d).collect();
if tokens.len() > c {
println!("{}", tokens[c]);
if let Some (count) = map.get_mut (tokens[c]) {
*count += 1;
} else {
map.insert (tokens[c].to_string(), 1);
}
}
}
我不知道有什么解决方案可以只在没有以前的条目时复制密钥,但仍然进行一次查找。