[英]How to split string into chunks in Rust to insert spaces
我正在嘗試學習 Rust。 我最近遇到的一個問題如下:給定一個String
,它恰好是 n 的某個倍數,我想將字符串拆分為大小為 n 的塊,並在這些塊之間插入一個空格,然后收集回一個單個字符串。
我遇到的問題是chars()
方法返回Chars
結構,由於某種原因它沒有實現SliceConcatExt
特征,因此無法調用chunks()
。
此外,一旦我成功創建了一個 Chunks 結構(通過調用.bytes()
代替),我不確定如何調用.join(' ')
因為元素現在是字節切片的Chunks
......
必須有一種優雅的方式來做到這一點,我錯過了。
例如,這是一個說明情況的輸入/輸出:
given: whatupmyname, 4
output: what upmy name
這是我寫得很糟糕的嘗試:
let n = 4;
let text = "whatupmyname".into_string();
text.chars()
// compiler error on chunks() call
.chunks(n)
.collect::<Vec<String>>()
.join(' ')
這里的問題是chars()
和bytes()
返回Iterator
s,而不是切片。 你可以使用as_bytes()
,它會給你一個&[u8]
。 但是,您不能直接從&str
中獲取&[char]
,因為只存在字節本身,並且char
必須通過查看並查看每個字節組成的字節數來創建。 你必須做這樣的事情:
text.chars()
.collect::<Vec<char>>()
.chunks(n)
.map(|c| c.iter().collect::<String>())
.collect::<Vec<String>>()
.join(" ");
但是,我不建議這樣做,因為它必須在此過程中為Vec
和String
分配大量臨時存儲空間。 相反,你可以做這樣的事情,它只需要分配來創建最終的String
。
text.chars()
.enumerate()
.flat_map(|(i, c)| {
if i != 0 && i % n == 0 {
Some(' ')
} else {
None
}
.into_iter()
.chain(std::iter::once(c))
})
.collect::<String>()
在最后一次收集之前,它一直作為迭代器,通過 flat_mapping 使用一個迭代器,該迭代器要么只是字符,要么是空格,然后是字符。
所以如果你想從一個字符列表中創建一個字符串,你可以使用fold 。
像這樣的東西:
text.chars
.enumerate()
.fold(String::new(), |acc, (i, c)| {
if i != 0 && i == n {
format!("{} {}", acc, c)
} else {
format!("{}{}", acc, c)
}
})
如果要拆分的數據大小是固定的,則:
use std::str;
fn main() {
let subs = "‌​‌​‌​​‌​‌".as_bytes()
.chunks(7)
.map(str::from_utf8)
.collect::<Result<Vec<&str>, _>>()
.unwrap();
println!("{:?}", subs);
}
// >> ["‌", "​", "‌", "​", "‌", "​", "​", "‌", "​", "‌"]
這樣一個簡單的任務可以用一個while
循環來解決:
fn main() {
let n = 4;
let text = "whatupmyname";
let mut it = text.chars().enumerate();
let mut rslt = String::from("");
while let Some((i, c)) = it.next() {
rslt.push(c);
if (i + 1) % n == 0 {
rslt.push(' ');
}
}
println!("{}", rslt);
}
為了完整起見,這里是 Chayim-Friedman 風格的循環(見評論) :
…
for (i, c) in text.chars().enumerate() {
rslt.push(c);
if (i + 1) % n == 0 {
rslt.push(' ');
}
}
…
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.