从字符串中获取随机字符并附加到另一个字符串

时间:2017-04-16 11:05:35

标签: string rust

我试图写下以下C ++代码的Rust等价物:

result += consonants[rand() % consonants.length()];

它意味着从字符串consonants中取一个随机字符并将其附加到字符串result

我似乎找到了一个有效的Rust等效物,但它至少可以说是怪异的。什么是更惯用的等价物?

format!("{}{}", result, consonants.chars().nth(rand::thread_rng().gen_range(1, consonants.chars().count())).unwrap().to_string());

1 个答案:

答案 0 :(得分:7)

一些事情:

  • 您不需要在此处使用format!()。有String::push()附加一个字符。

  • 还有rand::sample()函数可以从迭代器中随机选择多个元素。这看起来非常合适!

让我们看看它是如何组合在一起的!我为不同的用例创建了三个不同的版本。

1。 Unicode字符串(一般情况)

let consonants = "bcdfghjklmnpqrstvwxyz";
let mut result = String::new();

result.push(rand::sample(&mut rand::thread_rng(), consonants.chars(), 1)[0]);
//                                                                    |  |
//                             sample one element from the iterator --+  |
//                                                                       |
//                      get the first element from the returned vector --+

Playground

我们只从迭代器中采样一个元素并立即将其推送到字符串。仍然没有C&rand()那么简短,但请注意rand() is considered harmful用于任何严重用途!使用C ++的<random>标头要好得多,但也需要更多的代码。此外,您的C版本无法处理多字节字符(例如UTF-8编码),而Rust版本则支持完整的UTF-8。

2。 ASCII字符串

但是,如果你只想要一个带有英语辅音的字符串,那么就不需要UTF-8了,我们可以使用字节切片来使用O(1)索引:

use rand::{thread_rng, Rng};

let consonants = b"bcdfghjklmnpqrstvwxyz";
let mut result = String::new();

result.push(thread_rng().choose(consonants).cloned().unwrap().into());
//      convert Option<&u8> into Option<u8> ^^^^^^   
// unwrap, because we know `consonants` is not empty ^^^^^^
//                                   convert `u8` into `char` ^^^^

Playground

3。支持Unicode的字符集

正如评论中所提到的,你可能只想要一组字符(&#34;辅音&#34;)。这意味着,我们不必使用字符串,而是使用chars的数组。所以这是最后一个版本,它有UTF-8支持避免O(n)索引:

use rand::{thread_rng, Rng};

// If you need to avoid the heap allocation here, you can create a static
// array like this: let consonants = ['b', 'c', 'd', ...];
let consonants: Vec<_> = "bcdfghjklmnpqrstvwxyz".chars().collect();
let mut result = String::new();

result.push(*thread_rng().choose(&consonants).unwrap());

Playground