2016-11-03 4 views
2

私は2つの基準に基づいてベクトルをソートしています。最初はNaNになることができる浮動小数点であり、2番目は字句を辞書的に破るために使用される文字列です。NaNを他の数よりも大きく、他のNaNと等しくなるようにソートするにはどうしたらいいですか?

vec.sort_by(|a, b| { 
    match (foo(a) as f64/bar(a) as f64).partial_cmp(&(foo(b) as f64/bar(b) as f64)) { 
     Some(x) => { 
      Ordering::Equal => name(a).cmp(name(b)), 
      other => other, 
     } 
     None() => { 
      //Not sure what to put here. 
     } 
    } 
} 

foo(a)戻り整数> 0、 bar(a)返す整数> = 0、 name(a)戻る& String

NaNを他の数字より大きく、他のNaN(辞書順タイブレーカー)と等しく並べ替えるにはどうすればよいですか?

答えて

3

あなたは既にネクタイを扱う方法を知っています。必要なのは、浮動小数点を目的の方法で比較することだけです。

use std::cmp::Ordering; 
use std::f32; 

fn main() { 
    let mut vec = [91.0, f32::NAN, 42.0]; 

    vec.sort_by(|&a, &b| { 
     match (a.is_nan(), b.is_nan()) { 
      (true, true) => Ordering::Equal, 
      (true, false) => Ordering::Greater, 
      (false, true) => Ordering::Less, 
      (false, false) => a.partial_cmp(&b).unwrap(), 
     } 
    }); 

    println!("{:?}", vec); 
} 

をあなたが空想することと同様に、キーを表す構造体のそれを包むことができます::ちょうど...あなたが記述されたコードを書く

use std::cmp::Ordering; 
use std::f32; 

fn main() { 
    let mut vec = [91.0, f32::NAN, 42.0]; 

    vec.sort_by_key(|&a| MyNanKey(a)); 

    println!("{:?}", vec); 
} 

#[derive(Debug, Copy, Clone, PartialEq)] 
struct MyNanKey(f32); 

impl Eq for MyNanKey {} 

impl PartialOrd for MyNanKey { 
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> { 
     Some(self.cmp(other)) 
    } 
} 

impl Ord for MyNanKey { 
    fn cmp(&self, other: &Self) -> Ordering { 
     match (self.0.is_nan(), other.0.is_nan()) { 
      (true, true) => Ordering::Equal, 
      (true, false) => Ordering::Greater, 
      (false, true) => Ordering::Less, 
      (false, false) => self.0.partial_cmp(&other.0).unwrap(), 
     } 
    } 
} 

私は、この場合についての考え方もしませんでしたさまざまな無限大または非正規化された浮動小数点値に適用されるため、注意が必要です。

+0

私は 'MyNanKey'で笑ったし、なぜか分からない。 –

+0

@SimonWhiteheadそれは「サル」とはちょっと近いですね。 – Shepmaster

関連する問題