2016-05-09 24 views
1

max_by_keyを使用して、特定のキーに基づいてf64のベクトルから最大値を取得します。 f64Ordを実装していないので、私は浮動小数点のベクトルにmax_by_keyを使用する

src/satyrs/heuristics.rs:35:15: 35:38 error: the trait `core::cmp::Ord` is not implemented for the type `f64` [E0277] 
src/satyrs/heuristics.rs:35  *a.iter().max_by_key(|x| x.abs()).unwrap() 

同様に、sort_by_keyが同じエラーで失敗し得る、しかし

let a: Vec<f64> = vec![-3.0, 0.2, 1.4]; 
*a.iter().max_by_key(|n| n.abs()).unwrap() 

:これはキーのような小さなベクトルとabsで、簡単な例です:

a.sort_by_key(|n| n.abs()) 

浮動小数点ベクトルをでソートする部分順序制約を回避できます

b.sort_by(|m, n| m.partial_cmp(n).unwrap_or(Less)) 

が、それは私がaの各要素のための(この場合はabsで)キーを計算しましたため、ベクトルbに呼び出されなければならないだろう、と、私は戻って、見つけなければならないだろうaの対応する要素です。これは複雑で遅いようです。リスト内のアイテムの数が増えるにつれて、データの通過を最小限に抑えたいと思います。

どのような回避策ですか?

+2

ためのラッパー・タイプの(http://stackoverflow.com/questions/29884402/how-do-i-implement-ord-for-a-struct)[ 'Ord'実装]を' f64'。これにより、NaNの処理方法を定義する必要があります。 [例が存在する](http://stackoverflow.com/q/28247990/155423) – Shepmaster

答えて

2

ラッパータイプを作成しない場合は、ordered_floatまたはord_subsetクレートを使用できます。例えば

extern crate ordered_float; 
extern crate ord_subset; 

#[test] 
fn test_example_() { 
    use ordered_float::OrderedFloat; 
    // OrderedFloat -> NaN is greater than all other values and equal to itself. 
    // NotNaN -> NotNaN::new panics if called with NaN. 

    let mut a: Vec<f64> = vec![-3.0, 0.2, 1.4]; 

    let max = *a.iter().max_by_key(|n| OrderedFloat(n.abs())).unwrap(); 
    assert_eq!(-3.0, max); 

    a.sort_by_key(|n| OrderedFloat(n.abs())); 
    assert_eq!(vec![0.2, 1.4, -3.0], a); 
} 

#[test] 
fn test_example_ord_subset() { 
    use ord_subset::OrdSubsetIterExt; 

    let a: Vec<f64> = vec![-3.0, 0.2, 1.4]; 

    // For f64, NaN is ignored. 
    let max = *a.iter().ord_subset_max_by_key(|n| n.abs()).unwrap(); 
    assert_eq!(-3.0, max); 

    // ord_subset does not help with the sorting problem in the question 
} 
+0

ラッパータイプを実装しないでこれを行うための本質的な方法のようではないので、これを受け入れます。ありがとう! – jayelm

関連する問題