首页 > 解决方案 > 将具有空元素的字符串向量转换为连接的字符串向量

问题描述

我有一个Vec<&str>, 包含空字符串。我想写一个函数join_and_partition_on_empty,它返回一个Vec<&str>所有非空字符串用空格连接的地方,空字符串被删除,创建新的字符串开始。

// example test
assert_eq!(
   join_and_partition_on_empty(vec!["a", "", "b", "c", "", "d", "e" ],
   vec!["a", "b c", "d e" ]
)

我曾尝试使用迭代器 and fold,但在尝试连接字符串时遇到了所有权问题。

标签: stringvectorrust

解决方案


以下是否符合要求?

let input = vec!["a", "", "b", "c", "", "d", "e"];
let res = input
    .split(|s| s.is_empty())
    .filter(|s| !s.is_empty())
    .map(|s| s.join(" "))
    .collect::<Vec<_>>();
["a", "b c", "d e"]

如果需要,可以使用filter()删除由于连续的空字符串而导致的额外子切片。下面的输入将产生与上面列出的相同的输出:

let input = vec!["a", "", "", "", "", "b", "c", "", "d", "e"];

上述内容可能不如文档中.split()提到的那样有效,即为与谓词匹配的每个元素(即空字符串)创建子切片。

作为替代方案,这是一个命令式方法,由于忽略空字符串,它可能会更高效:

let input = vec!["a", "", "b", "c", "", "d", "e" ];

let mut res = vec![];
let mut group = vec![];

for s in input.iter() {
    if !s.is_empty() {
        group.push(&s[..]);
    } else if !group.is_empty() {
        res.push(group.join(" "));
        group.clear();
    }
}

// Push any remaining values
if !group.is_empty() {
    res.push(group.join(" "));
}

推荐阅读