2016-11-03 2 views
2

Ich sortiere einen Vektor nach zwei Kriterien. Der erste ist ein Gleitkomma, der NaN sein kann, der zweite ist eine Zeichenfolge, die verwendet wird, um Bindungen lexikografisch zu brechen.Wie sortiere ich `NaN` so, dass es größer ist als jede andere Zahl und gleich einem anderen` 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) kehrt int> 0, bar(a) kehrt int> = 0, name(a) kehrt & String.

Wie sortiere ich NaN, so dass es größer als jede andere Nummer und gleich anderen NaN (lexikographischer Tie-Breaker) ist?

Antwort

3

Sie wissen bereits, wie man mit Bindungen umgeht, alles was Sie brauchen ist, Fließkommazahl in der gewünschten Weise zu vergleichen. Nur ... schreiben Sie den Code, den Sie beschrieben:

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); 
} 

könnten Sie Lust sein und dass in einer Struktur einpacken, die den Schlüssel als auch darstellt:

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(), 
     } 
    } 
} 

Ich habe keine Gedanken darüber, ob diese wäre für die verschiedenen Unendlichkeiten oder denormalisierten Gleitkommawerte anwendbar, also Vorsicht.

+0

Ich lachte über 'MyNanKey' und ich weiß nicht warum. –

+0

@SimonWhitehead it * ist schrecklich nah an "Affen", oder? – Shepmaster