如何实现Vec< u8>的修整? [英] How to implement trim for Vec<u8>?

查看:97
本文介绍了如何实现Vec< u8>的修整?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Rust为字符串提供了一种修整方法: str.trim()删除前导和尾随空格.我想要一种对字节字符串执行相同操作的方法.应该使用 Vec< u8> 并删除开头和结尾的空格(空格,0x20和htab,0x09).

Rust provides a trim method for strings: str.trim() removing leading and trailing whitespace. I want to have a method that does the same for bytestrings. It should take a Vec<u8> and remove leading and trailing whitespace (space, 0x20 and htab, 0x09).

编写 trim_left()很容易,您可以将迭代器与 skip_while()一起使用:

Writing a trim_left() is easy, you can just use an iterator with skip_while(): Rust Playground

fn main() {
    let a: &[u8] = b"     fo o ";
    let b: Vec<u8> = a.iter().map(|x| x.clone()).skip_while(|x| x == &0x20 || x == &0x09).collect();
    println!("{:?}", b);
}

但是要修剪合适的字符,如果在找到空格后列表中没有其他字母,我将需要向前看.

But to trim the right characters I would need to look ahead if no other letter is in the list after whitespace was found.

推荐答案

这是一个返回切片的实现,而不是新的 Vec< u8> ,作为 str :: trim().它也可以在 [u8] 上实现,因为它比 Vec< u8> 更通用(您可以廉价地从向量中获得一个切片,但是从切片中创建向量是成本更高,因为它涉及堆分配和副本).

Here's an implementation that returns a slice, rather than a new Vec<u8>, as str::trim() does. It's also implemented on [u8], since that's more general than Vec<u8> (you can obtain a slice from a vector cheaply, but creating a vector from a slice is more costly, since it involves a heap allocation and a copy).

trait SliceExt {
    fn trim(&self) -> &Self;
}

impl SliceExt for [u8] {
    fn trim(&self) -> &[u8] {
        fn is_whitespace(c: &u8) -> bool {
            *c == b'\t' || *c == b' '
        }

        fn is_not_whitespace(c: &u8) -> bool {
            !is_whitespace(c)
        }

        if let Some(first) = self.iter().position(is_not_whitespace) {
            if let Some(last) = self.iter().rposition(is_not_whitespace) {
                &self[first..last + 1]
            } else {
                unreachable!();
            }
        } else {
            &[]
        }
    }
}

fn main() {
    let a = b"     fo o ";
    let b = a.trim();
    println!("{:?}", b);
}

如果确实需要在 trim()之后的 Vec< u8> ,则只需在切片上调用 into()即可将其转换为 Vec< u8> .

If you really need a Vec<u8> after the trim(), you can just call into() on the slice to turn it into a Vec<u8>.

fn main() {
    let a = b"     fo o ";
    let b: Vec<u8> = a.trim().into();
    println!("{:?}", b);
}

这篇关于如何实现Vec&lt; u8&gt;的修整?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆