Более сжатая инициализация HashMap
Я использую HashMap
для подсчета вхождений разных символов в строке:
let text = "GATTACA";
let mut counts: HashMap<char, i32> = HashMap::new();
counts.insert('A', 0);
counts.insert('C', 0);
counts.insert('G', 0);
counts.insert('T', 0);
for c in text.chars() {
match counts.get_mut(&c) {
Some(x) => *x += 1,
None => (),
}
}
Есть ли более сжатый или декларативный способ инициализации HashMap
? Например, в Python я бы сделал:
counts = { 'A': 0, 'C': 0, 'G': 0, 'T': 0 }
или
counts = { key: 0 for key in 'ACGT' }
Ответы
Ответ 1
Вы можете использовать итераторы для эмуляции понимания словаря, например
let counts = "ACGT".chars().map(|c| (c, 0_i32)).collect::<HashMap<_, _>>();
или даже for c in "ACGT".chars() { counts.insert(c, 0) }
.
Кроме того, можно написать макрос, чтобы обеспечить краткую инициализацию произвольных значений.
macro_rules! hashmap {
($( $key: expr => $val: expr ),*) => {{
let mut map = ::std::collections::HashMap::new();
$( map.insert($key, $val); )*
map
}}
}
используется как let counts = hashmap!['A' => 0, 'C' => 0, 'G' => 0, 'T' => 0];
.
Ответ 2
Еще один способ, который я вижу в официальном документе:
https://doc.rust-lang.org/std/collections/struct.HashMap.html
use std::collections::HashMap;
fn main() {
let timber_resources: HashMap<&str, i32> =
[("Norway", 100),
("Denmark", 50),
("Iceland", 10)]
.iter().cloned().collect();
// use the values stored in map
}