You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Rust函数式API按空行分割生成&str类型的二维向量?

用Rust函数式API分割Advent of Code 2022第11题的猴子数据块

问题描述

我正在完成Advent of Code 2022第11题,输入为一段&str格式的猴子数据(示例输入如下):

Monkey 0:
    Starting items: 52, 60, 85, 69, 75, 75
    Operation: new = old * 17
    Test: divisible by 13
      If true: throw to monkey 6
      If false: throw to monkey 7
  
  Monkey 1:
    Starting items: 96, 82, 61, 99, 82, 84, 85
    Operation: new = old + 8
    Test: divisible by 7
      If true: throw to monkey 0
      If false: throw to monkey 7
  
  Monkey 2:
    Starting items: 95, 79
    Operation: new = old + 6
    Test: divisible by 19
      If true: throw to monkey 5
      If false: throw to monkey 3

希望用Rust的函数式API(如map、filter、fold等)按空行分割每个猴子的数据块,生成Vec<Vec<&str>>类型的结果,示例输出如下:

[["Monkey 0:", "    Starting items: 52, 60, 85, 69, 75, 75", "    Operation: new = old * 17", "    Test: divisible by 13", "      If true: throw to monkey 6", "      If false: throw to monkey 7"], ["  Monkey 1:", "    Starting items: 96, 82, 61, 99, 82, 84, 85", "    Operation: new = old + 8", "    Test: divisible by 7", "      If true: throw to monkey 0", "      If false: throw to monkey 7"]]

我已用命令式方式实现,但不清楚如何用更符合Rust风格的函数式方式完成。

函数式实现方案

方案一:用fold逐行构建结果

fn split_monkeys(input: &str) -> Vec<Vec<&str>> {
    input
        .lines()
        .filter(|line| !line.trim().is_empty()) // 过滤所有空白行
        .fold(Vec::new(), |mut acc, line| {
            // 识别猴子起始行,新增子向量
            if line.trim_start().starts_with("Monkey") {
                acc.push(Vec::new());
            }
            // 将当前行加入最后一个猴子的向量中
            acc.last_mut().unwrap().push(line);
            acc
        })
}

// 使用示例
fn main() {
    let input = "Monkey 0:\n    Starting items: 52, 60, 85, 69, 75, 75\n    Operation: new = old * 17\n    Test: divisible by 13\n      If true: throw to monkey 6\n      If false: throw to monkey 7\n  \n  Monkey 1:\n    Starting items: 96, 82, 61, 99, 82, 84, 85\n    Operation: new = old + 8\n    Test: divisible by 7\n      If true: throw to monkey 0\n      If false: throw to monkey 7\n  \n  Monkey 2:\n    Starting items: 95, 79\n    Operation: new = old + 6\n    Test: divisible by 19\n      If true: throw to monkey 5\n      If false: throw to monkey 3";
    
    let monkeys = split_monkeys(input);
    println!("{:?}", monkeys);
}

代码说明

  1. 过滤空行:通过lines()拆分输入后,用filter移除所有仅含空白字符的行。
  2. 折叠构建:用fold初始化空结果集,遍历每行时:
    • 判断当前行是否为猴子的起始行(去掉前置空格后以"Monkey"开头),是则新增一个子向量。
    • 将当前行追加到结果集的最后一个子向量中。

方案二:用split按块拆分(更简洁)

fn split_monkeys(input: &str) -> Vec<Vec<&str>> {
    input
        .split("\n\n") // 按空行直接拆分猴子块
        .map(|block| {
            block
                .lines()
                .filter(|line| !line.trim().is_empty()) // 过滤块内的空白行
                .collect()
        })
        .collect()
}

代码说明

  1. 块级拆分:split("\n\n")直接将输入分割为每个猴子对应的文本块。
  2. 行处理:对每个块拆分行、过滤空行后,收集为Vec<&str>。
  3. 结果收集:将所有处理后的块收集为最终的Vec<Vec<&str>>。

这种写法逻辑更直观,完全遵循函数式风格,推荐使用。

内容的提问来源于stack exchange,提问作者Mlengcivil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 10:01:20