【问题标题】:What's an efficient way to transform a two dimensional array of labels to a map from label to coordinates?将二维标签数组转换为从标签到坐标的地图的有效方法是什么?
【发布时间】:2017-05-24 06:43:08
【问题描述】:

以下代码可以工作,但会在整个数组上进行多次传递,我想避免这种情况。另一种选择是按名称对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);
        }
    }
}

【问题讨论】:

    标签: arrays iterator rust


    【解决方案1】:

    使用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);
    }
    

    高效:单次遍历数据和每个项目的单次哈希查找。

    简单:美在旁观者的眼中。

    【讨论】:

    • 这和我想的一样。基准测试显示它快 1.7 倍。
    猜你喜欢
    • 1970-01-01
    • 2012-01-22
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 2020-08-07
    • 1970-01-01
    • 2010-12-11
    相关资源
    最近更新 更多