我正在基于整数数组创建直方图。下面的代码工作正常,但看起来很糟糕,因为我必须手动编写很多匹配臂。但感觉应该有更好的方法来做到这一点,我认为这种方法是一个宏。你能指出我正确的方向吗?
pub fn make_histogram(array: &[u64]) {
let mut counts = HashMap::new();
for value in array.iter() {
match value {
1..=2000 => *counts.entry("1-2000").or_insert(0) += 1,
2001..=4000 => *counts.entry("2001-4000").or_insert(0) += 1,
4001..=6000 => *counts.entry("4001-6000").or_insert(0) += 1,
6001..=8000 => *counts.entry("6001-8000").or_insert(0) += 1,
8001..=10000 => *counts.entry("8001-10000").or_insert(0) += 1,
10001..=12000 => *counts.entry("10001-12000").or_insert(0) += 1,
12001..=14000 => *counts.entry("12001-14000").or_insert(0) += 1,
14001..=16000 => *counts.entry("14001-16000").or_insert(0) += 1,
16001..=18000 => *counts.entry("16001-18000").or_insert(0) += 1,
18001..=20000 => *counts.entry("18001-20000").or_insert(0) += 1,
20001..=22000 => *counts.entry("20001-22000").or_insert(0) += 1,
22001..=24000 => *counts.entry("22001-24000").or_insert(0) += 1,
24001..=26000 => *counts.entry("24001-26000").or_insert(0) += 1,
26001..=28000 => *counts.entry("26001-28000").or_insert(0) += 1,
28001..=30000 => *counts.entry("28001-30000").or_insert(0) += 1,
30001..=32000 => *counts.entry("30001-32000").or_insert(0) += 1,
32001..=34000 => *counts.entry("32001-34000").or_insert(0) += 1,
34001..=36000 => *counts.entry("34001-36000").or_insert(0) += 1,
36001..=38000 => *counts.entry("36001-38000").or_insert(0) += 1,
38001..=40000 => *counts.entry("38001-40000").or_insert(0) += 1,
40001..=42000 => *counts.entry("40001-42000").or_insert(0) += 1,
42001..=44000 => *counts.entry("42001-44000").or_insert(0) += 1,
44001..=46000 => *counts.entry("44001-46000").or_insert(0) += 1,
46001..=48000 => *counts.entry("46001-48000").or_insert(0) += 1,
48001..=50000 => *counts.entry("48001-50000").or_insert(0) += 1,
50001..=52000 => *counts.entry("50001-52000").or_insert(0) += 1,
52001..=54000 => *counts.entry("52001-54000").or_insert(0) += 1,
54001..=56000 => *counts.entry("54001-56000").or_insert(0) += 1,
56001..=58000 => *counts.entry("56001-58000").or_insert(0) += 1,
58001..=60000 => *counts.entry("58001-60000").or_insert(0) += 1,
_ => *counts.entry("60001-inf").or_insert(0) += 1,
}
}
Run Code Online (Sandbox Code Playgroud)
尽管有标题,但您的问题表明您正在寻找问题的解决方案,不一定需要涉及手臂HashMap或匹配手臂。
如果性能对您很重要,我宁愿考虑使用数组,而不是HashMap. 看来你的步骤是固定的,所以你可以写这样的东西:
use std::cmp;
const STEP_SIZE: u64 = 2_000;
const STEPS_COUNT: usize = 30;
// ...
let mut counts = [0; STEPS_COUNT];
// ...
for value in array {
let idx = cmp::min(((value - 1) / STEP_SIZE) as usize, STEPS_COUNT-1);
counts[idx] += 1;
}
Run Code Online (Sandbox Code Playgroud)
您在 as 键中使用的范围字符串HashMap看起来像是您可以在需要时构造的东西。您可以每次(即时)执行此操作,也可以生成一次字符串并缓存它们(例如在Strings 数组中)。