web-dev-qa-db-ja.com

RustのスライスまたはVecの最大または最小の浮動小数点値のインデックスを取得する慣用的な方法は何ですか?

仮定-Vec<f32>notNaNの値があるか、またはNaNの動作を示します。

次のサンプルセットを見てください。

0.28  
0.3102
0.9856
0.3679
0.3697
0.46  
0.4311
0.9781
0.9891
0.5052
0.9173
0.932 
0.8365
0.5822
0.9981
0.9977

上記のリストで最も高い値のindexを取得する最も簡単で最も安定した方法は何ですか?

私の最初の試みは次の行に沿っていました:

let _tmp = *nets.iter().max_by(|i, j| i.partial_cmp(j).unwrap()).unwrap();    
let _i = nets.iter().position(|&element| element == _tmp).unwrap();

ここで、nets&Vec<f32>。私にはこれは明らかに間違っているようです。

Pythonこれは、上記の仮定を考慮に入れて機能する)と同等です。

_i = nets.index(max(nets))
6
Juxhin

私はおそらくこのようなことをするでしょう:

fn main() -> Result<(), Box<std::error::Error>> {
    let samples = vec![
        0.28, 0.3102, 0.9856, 0.3679, 0.3697, 0.46, 0.4311, 0.9781, 0.9891, 0.5052, 0.9173, 0.932,
        0.8365, 0.5822, 0.9981, 0.9977,
    ];

    // Use enumerate to get the index
    let mut iter = samples.iter().enumerate();
    // we get the first entry
    let init = iter.next().ok_or("Need at least one input")?;
    // we process the rest
    let result = iter.try_fold(init, |acc, x| {
        // return None if x is NaN
        let cmp = x.1.partial_cmp(acc.1)?;
        // if x is greater the acc
        let max = if let std::cmp::Ordering::Greater = cmp {
            x
        } else {
            acc
        };
        Some(max)
    });
    println!("{:?}", result);

    Ok(())
}

これは、たとえば関数try_max_byを使用して、イテレーターに特性を追加することで実装できます。

2
Stargateur