将数组转换为 HashMap 的更简单方法

Win*_*ton 1 rust

以下代码将数组中每种颜色的最大值转换为哈希图。也在Rust Playground中。

use std::collections::HashMap;
use std::cmp;

fn main() {
    let array = [
        ("blue", 1),
        ("green", 2),
        ("red", 3),
        ("blue", 4),
        ("green", 1),
        ("red", 2),
    ];
    
    let mut scores = HashMap::new();
    
    // Convert array of key value into hashmap
    array
        .into_iter()
        .for_each(|(color, color_count)| {
            // Update the HashMap
            scores
                .entry(color)
                .and_modify(|e| { *e = cmp::max(*e, color_count) })
                .or_insert(color_count);
        });

    for (key, value) in &scores {
        println!("{}: {}", key, value);
    }
    
    println!("The product of the values: {}", scores.values().cloned().fold(1, |res, a| res * a));
}
Run Code Online (Sandbox Code Playgroud)

它将得到以下打印输出:

blue: 4
green: 2
red: 3
The product of the values: 24
Run Code Online (Sandbox Code Playgroud)

我面临的问题是收集的数据array来自另一个map函数。HashMap但我面临的问题是,如果我直接将数组转换为HashMap将存储最新条目(数组的底部)。我相信有一些更简洁的方法来链接整个事物以使其看起来更整洁?

pro*_*-fh 7

作为一个小改动,我建议使用入口API,以避免第一次搜索.get()和第二次搜索.insert(),但这与您自己的最初尝试没有太大不同。

    let mut scores = HashMap::<&str, usize>::new();
    for (color, color_count) in array {
        scores
            .entry(color)
            .and_modify(|c| *c = (*c).max(color_count))
            .or_insert(color_count);
    }
Run Code Online (Sandbox Code Playgroud)

在不使用哈希图的情况下,计算产品的一种完全不同的方式是依赖不稳定的.group_by()功能(然后用nightly编译)。

#![feature(slice_group_by)]

fn main() {
    let mut array = [
        ("blue", 1),
        ("green", 2),
        ("red", 3),
        ("blue", 4),
        ("green", 1),
        ("red", 2),
    ];

    array.sort_unstable();
    let p = array
        .group_by(|a, b| a.0 == b.0)
        .map(|g| g.last().unwrap().1)
        .product::<usize>();
    println!("product: {:?}", p);
}
/*
product: 24
*/
Run Code Online (Sandbox Code Playgroud)

不依赖不稳定的功能,我们可以使用itertools

use itertools::Itertools;

fn main() {
    let mut array = [
        ("blue", 1),
        ("green", 2),
        ("red", 3),
        ("blue", 4),
        ("green", 1),
        ("red", 2),
    ];

    array.sort_unstable_by(|a, b| b.cmp(a));
    let p = array
        .into_iter()
        .dedup_by(|a, b| a.0 == b.0)
        .map(|e| e.1)
        .product::<usize>();
    println!("product: {:?}", p);
}
/*
product: 24
*/
Run Code Online (Sandbox Code Playgroud)

我们可以(在内部)回到哈希图......

use itertools::Itertools;

fn main() {
    let array = [
        ("blue", 1),
        ("green", 2),
        ("red", 3),
        ("blue", 4),
        ("green", 1),
        ("red", 2),
    ];

    let p = array
        .into_iter()
        .into_grouping_map()
        .max()
        .into_values()
        .product::<usize>();
    println!("product: {:?}", p);
}
/*
product: 24
*/
Run Code Online (Sandbox Code Playgroud)

  • 如果可能的话,优先选择“sort_unstable()”而不是“sort()”。 (2认同)