如何将Vec<Vec<f64>>转换为字符串

4
我是新手Rust开发者,目前在处理一个简单的任务时遇到了困难。我想将一个矩阵转换成一个字符串,并用制表符分隔各个字段。我认为可以使用map函数或类似的方法来实现,但无论我尝试什么都会出错。
这是我的代码,我想将col部分转换为一个函数,该函数返回一个用制表符分隔的字符串,我可以打印输出。在Python中,这类似于row.join("\t")。在Rust中是否有类似的功能?
fn print_matrix(vec: &Vec<Vec<f64>>) {
    for row in vec.iter() {
        for col in row.iter() {
           print!("\t{:?}",col);
        }
        println!("\n");
    }
}

这段代码哪里出了问题?你能在Playpen上提供一个最小完整的示例吗?这段代码似乎没有任何问题。 - Simon Whitehead
它应该打印字符串<制表符>字符串<制表符>字符串,但它会打印一个前导制表符。必须有比这更优雅的解决方案,而不需要调整。 - Mandragor
请参考 https://doc.rust-lang.org/std/fmt/#format_args 下的示例。 - starblue
2个回答

7

标准库中确实有一个join函数,但它并不是非常有用(通常需要额外的内存分配)。不过你可以在这里找到一个解决方案:

fn print_matrix(vec: &Vec<Vec<f64>>) {
    for row in vec {
        let cols_str: Vec<_> = row.iter().map(ToString::to_string).collect();
        let line = cols_str.join("\t");
        println!("{}", line);
    }
}

问题在于此join适用于切片而不是迭代器。我们必须首先将所有元素转换为字符串,将结果收集到一个新向量中,然后才能使用join

箱子itertools为迭代器定义了一个join方法,可以这样应用:

for row in vec {
    let line = row.iter().join("\t");
    println!("{}", line);
}

为了避免使用任何已命名的功能,当然可以手动完成:
for row in vec {
    if let Some(first) = row.get(0) {
        print!("{}", first);            
    }
    for col in row.iter().skip(1) {
        print!("\t{}", col);
    }
    println!("");
}

4
除了使用itertools中的join之外,您还可以始终在迭代器上使用fold(非常有用),像这样:
row.iter().fold("", |tab, col| { print!("{}{:?}", tab, col); "\t" });

这将以一个额外的\t结尾。 - tafia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接