以下代码可以正常工作,但会对整个数组进行多次传递,我希望避免这种情况。另一个替代方法是按名称对named_coords
数组进行排序,然后在迭代排序数组时收集pieces
,但我没有找到一种干净的方法来完成这项工作。理想情况下,答案将使用标准适配器等来整合集合。
use std::collections::HashMap;
fn main() {
let p = [ ['I', 'P', 'P', 'Y', 'Y', 'Y', 'Y', 'V', 'V', 'V']
, ['I', 'P', 'P', 'X', 'Y', 'L', 'L', 'L', 'L', 'V']
, ['I', 'P', 'X', 'X', 'X', 'F', 'Z', 'Z', 'L', 'V']
, ['I', 'T', 'W', 'X', 'F', 'F', 'F', 'Z', 'U', 'U']
, ['I', 'T', 'W', 'W', 'N', 'N', 'F', 'Z', 'Z', 'U']
, ['T', 'T', 'T', 'W', 'W', 'N', 'N', 'N', 'U', 'U']
];
// Gather named coordinates into a Vec
let mut named_coords = Vec::new();
for (n0, j0) in p.iter().enumerate() {
for (n1, j1) in j0.iter().enumerate() {
named_coords.push(((n0, n1), *j1));
}
}
// Transform the named coordinates into Vector of names.
let mut names = named_coords.iter().map(|x| x.1).collect::<Vec<_>>();
names.sort();
names.dedup();
// Filter the named coordinates by name and collect results.
// Inefficient - iterates over entire named_coords vector multiple times.
let mut pieces = HashMap::new();
for name in names {
pieces.insert(name, named_coords.iter().filter(|&p| p.1 == name).map(|p| p.0).collect::<Vec<_>>());
}
// Print out results.
for n in pieces.iter() {
for coord in n.1.iter() {
println!("{} {} {}", n.0, coord.0, coord.1);
}
}
}
答案 0 :(得分:3)
使用entry
API:
use std::collections::HashMap;
fn main() {
let p = [['I', 'P', 'P', 'Y', 'Y', 'Y', 'Y', 'V', 'V', 'V'],
['I', 'P', 'P', 'X', 'Y', 'L', 'L', 'L', 'L', 'V'],
['I', 'P', 'X', 'X', 'X', 'F', 'Z', 'Z', 'L', 'V'],
['I', 'T', 'W', 'X', 'F', 'F', 'F', 'Z', 'U', 'U'],
['I', 'T', 'W', 'W', 'N', 'N', 'F', 'Z', 'Z', 'U'],
['T', 'T', 'T', 'W', 'W', 'N', 'N', 'N', 'U', 'U']];
let mut pieces = HashMap::new();
for (n0, j0) in p.iter().enumerate() {
for (n1, j1) in j0.iter().enumerate() {
pieces.entry(j1).or_insert_with(Vec::new).push((n0, n1));
}
}
println!("{:?}", pieces);
}
高效:单个传递数据和每个项目的单个哈希查找。
简单:美丽在旁观者的眼中。