首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >锈蚀:将嵌套结构扁平为Vec<T>

锈蚀:将嵌套结构扁平为Vec<T>
EN

Code Review用户
提问于 2019-03-07 13:09:48
回答 1查看 1.9K关注 0票数 3

我有一个结构,它嵌套其他结构,如下所示:

代码语言:javascript
复制
#[derive(Debug)]
pub struct Rankings {
    conferences: Vec,
}

#[derive(Debug)]
pub struct Conference {
    divisions: Vec,
}

#[derive(Debug)]
pub struct Division {
    teams: Vec,
}

#[derive(Debug, Clone)]
pub struct Team {
    name: String,
    market: String,
}

我想要做的是将Rankings实例转换为Vec。这是我的解决方案:

代码语言:javascript
复制
fn main() {
    let mut rankings = Rankings {
        conferences: vec![
            Conference {
                divisions: vec![
                    Division {
                        teams: vec![
                            Team {
                                name: String::from("Raptors"),
                                market: String::from("Toronto"),
                            },
                            Team {
                                name: String::from("Knicks"),
                                market: String::from("New York"),
                            }
                        ]
                    },
                    Division {
                        teams: vec![
                            Team {
                                name: String::from("Bucks"),
                                market: String::from("Milwaukee"),
                            },
                            Team {
                                name: String::from("Cavaliers"),
                                market: String::from("Cleveland"),
                            }
                        ]
                    },
                ]
            },
        ]
    };

    println!("- rankings:\n{:#?}\n", rankings);

    let mut raw_teams: Vec>> = rankings
        .conferences
        .iter_mut()
        .map(|c| c.divisions.iter_mut().map(|d| d.teams.clone()).collect())
        .collect();

    println!("- raw_teams:\n{:#?}\n", raw_teams);

    let flattened_teams = raw_teams
        .iter_mut()
        .fold(Vec::new(), |mut acc, val| {
            acc.append(val);
            acc
        })
        .iter_mut()
        .fold(Vec::new(), |mut acc, val| {
            acc.append(val);
            acc
        });

    println!("- flattened_teams:\n{:#?}\n", flattened_teams);
}

操场链接

首先,我使用Rankingsmap()Vec>>转换为Vec>>,然后使用iter_mut()fold()D9还原为Vec

但我只是编写了避免编译错误的代码,这意味着使用惯用模式可以更好地重构代码。我认为我可能过度使用可变性,可以使用适当的迭代器函数简化两个转换过程。谢谢你的建议。

EN

回答 1

Code Review用户

回答已采纳

发布于 2019-03-07 14:01:15

首先,没有必要在conferences上使用D1,因为您从不更改原始的rankings。当我们稍后使用clone时,我们可以简单地使用

代码语言:javascript
复制
let mut raw_teams: Vec>> = rankings
    .conferences
    .iter()
    .map(|c| c.divisions.iter().map(|d| d.teams.clone()).collect())
    .collect();

现在我们有了一个Vec>,我们可以调用flatten

代码语言:javascript
复制
let flattened_teams: Vec = raw_teams.into_iter().flatten().flatten().collect();

我使用into_iter()作为您的原始代码,使raw_teams保持为空。

但是,如果我们使用的是raw_teams而不是map(…).flatten(),则可以跳过D12

代码语言:javascript
复制
let flattened_teams: Vec = rankings
    .conferences
    .iter()
    .flat_map(|c| &c.divisions) // need to borrow due to iter()
    .flat_map(|d| &d.teams)     // need to borrow due to iter()
    .cloned()                   // clone the elements
    .collect();

如果我们不想借用,我们当然可以将所有东西移到flattened_teams中,只需简单地删除cloned()&

代码语言:javascript
复制
let flattened_teams : Vec = rankings
    .conferences
    .into_iter()
    .flat_map(|c| c.divisions)
    .flat_map(|d| d.teams)
    .collect()

这些函数中没有一个使用mut

票数 3
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/214918

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档