【问题标题】:How can I randomly select one element from a vector or array?如何从向量或数组中随机选择一个元素?
【发布时间】:2015-12-11 02:41:26
【问题描述】:

我有一个向量,其中元素是(String, String)。如何随机选择这些元素之一?

【问题讨论】:

    标签: rust


    【解决方案1】:

    你想要rand crate,特别是choose 方法。

    use rand::seq::SliceRandom; // 0.7.2
    
    fn main() {
        let vs = vec![0, 1, 2, 3, 4];
        println!("{:?}", vs.choose(&mut rand::thread_rng()));
    }
    

    【讨论】:

    • 我不同意。这种方法和其他语言的唯一区别是需要将特征放在范围内,并且需要手动指定 rng 状态的来源。也许比平时更明确一点,但我觉得还可以。
    【解决方案2】:

    使用choose_multiple

    use rand::seq::SliceRandom; // 0.7.2
    
    fn main() {
        let samples = vec!["hi", "this", "is", "a", "test!"];
        let sample: Vec<_> = samples
            .choose_multiple(&mut rand::thread_rng(), 1)
            .collect();
        println!("{:?}", sample);
    }
    

    【讨论】:

      【解决方案3】:

      已经包含在rand crate 中的加权采样的另一个选择是WeightedIndex,它有一个示例:

      use rand::prelude::*;
      use rand::distributions::WeightedIndex;
      
      let choices = ['a', 'b', 'c'];
      let weights = [2,   1,   1];
      let dist = WeightedIndex::new(&weights).unwrap();
      let mut rng = thread_rng();
      for _ in 0..100 {
          // 50% chance to print 'a', 25% chance to print 'b', 25% chance to print 'c'
          println!("{}", choices[dist.sample(&mut rng)]);
      }
      
      let items = [('a', 0), ('b', 3), ('c', 7)];
      let dist2 = WeightedIndex::new(items.iter().map(|item| item.1)).unwrap();
      for _ in 0..100 {
          // 0% chance to print 'a', 30% chance to print 'b', 70% chance to print 'c'
          println!("{}", items[dist2.sample(&mut rng)].0);
      }
      

      【讨论】:

        【解决方案4】:

        如果您想选择多个元素,那么random_choice crate 可能适合您:

        extern crate random_choice;
        use self::random_choice::random_choice;
        
        fn main() {
            let mut samples = vec!["hi", "this", "is", "a", "test!"];
            let weights: Vec<f64> = vec![5.6, 7.8, 9.7, 1.1, 2.0];
        
            let number_choices = 100;
            let choices = random_choice().random_choice_f64(&samples, &weights, number_choices);
        
            for choice in choices {
                print!("{}, ", choice);
            }
        }
        

        【讨论】:

          【解决方案5】:

          如果您还想删除所选元素,这是一种方法(使用rand crate):

          let mut vec = vec![0,1,2,3,4,5,6,7,8,9];
          
          let index = (rand::random::<f32>() * vec.len() as f32).floor() as usize;
          let value = vec.remove( index );
          
          println!("index: {} value: {}", index, value);
          println!("{:?}", vec);
          

          Rust Playground

          remove(index) 删除 index 处的值(将其后的所有元素向左移动)并返回 index (docs) 处的值。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-07-23
            • 2014-04-21
            • 2016-03-26
            • 1970-01-01
            • 2011-06-30
            • 1970-01-01
            相关资源
            最近更新 更多