2017-04-04 4 views
5

Beispiel Eingabe:Sortierreihen von Bereichen ['55 -66 ','> 55 ',' <66 ']?

[ '50-59', '60-69', '40-49', '>=70', '<40' ] 

Erwarteter Ausgang

[ '<40', '40-49', '50-59', '60-69', '>=70' ] 

Attempt; erweitert aus meinem frühen Einzeiler (zum Debuggen):

export function sort_ranges(ranges: string[]): string[] { 
    const collator = new Intl.Collator(undefined, { 
     numeric: true, 
     sensitivity: 'base', 
     ignorePunctuation: true 
    }); 
    return ranges.sort((a: string, b: string): number => { 
      const bNaN: boolean = !isNaN(parseInt(b[0])); 
      const col =() => 
       console.info(`collator(${a}, ${b}) = ${collator.compare(a, b)}` 
          ) || collator.compare(a, b); 
      if (a[0] === '<' && bNaN) { 
       console.info('< =', a); 
       return -1; 
      } 
      else if (a[0] === '>' || b[0] === '>') { 
       console.info('> =', a); 
       return 1; 
      } 
      else return col(); 
     } 
    ); 
} 

Runnable (mocha+chai in a plnkr)

Hinweis: Bereiche werden garantiert nicht überlappend sein, und es andere Dinge in der Anordnung wie ‚foo‘, das sollte sein in beliebiger Reihenfolge am Ende des Arrays platziert werden.

Ideen: Ich könnte ein neues Array wie [[50,59], ['<', '40']] dann versuchen, überschreiben die .sort Methode wieder, aber das scheint verrückt. Gibt es eine bessere Lösung?

+3

ich nicht, warum ist die '' 60-69' und 50-59' vor '40-49' in dem erwarteten Ergebnis. –

+0

Whoops, mein Schlechter; kopiert es in Eile –

+2

Wo würde 51-57 gehen? – mplungjan

Antwort

0

Leider sind die anderen Antworten Grenzfälle nicht handhaben. Als zusätzlichen Bonus, keine regex:

function sort_ranges(ranges/*: string[]*/)/*: string[]*/ { 
 
    return ranges.sort((a/*: string*/, b/*: string*/)/*: number*/ => { 
 
     if (a[0] === '<') return -1; 
 
     else if (a[0] === '>') return a[0].charCodeAt() - b[0].charCodeAt(); 
 
     else if (isNaN(parseInt(a[0])) || b[0] === '<') return 1; 
 
     else if (b[0] === '>' || isNaN(parseInt(b[0]))) return -1; 
 
     return parseInt(a.split('-')[0]) - parseInt(b.split('-')[0]) 
 
    }); 
 
} 
 

 
// Test code for StackOverflow: 
 

 
const expected_arrays = Object.freeze([ 
 
    [ '<40', '40-49', '50-59', '60-69', '>=70' ], 
 
    [ '40-49', '50-59', '60-69', '>=70', 'all' ] 
 
]); 
 

 
const input_arrays = Object.freeze([ 
 
    [ '60-69', '<40', '>=70', '50-59', '40-49' ], 
 
    [ '50-59', 'all', '40-49', '>=70', '60-69' ] 
 
]); 
 

 
for(let i=0; i<input_arrays.length; i++) 
 
    console.info(sort_ranges(input_arrays[i]), '===', expected_arrays[i]);

7

var a = [ '50-59', '60-69', '40-49', '>=70', '<40' ]; 
 

 
a.sort(function(a,b) { 
 
    if (a[0] === '<') return -1; 
 
    if (a[0] === '>') return 1; 
 
    if (b[0] === '<') return 1; 
 
    if (b[0] === '>') return -1; 
 
    return a.match(/\d+/)[0] - b.match(/\d+/)[0]; 
 
}); 
 

 
console.dir(a);

2

Sie könnten enthaltenen Zahlen und wenn zwei Zahlen verfügbar sind, nehmen Sie es für ein bereinigtes Art.

var array = ['50-59', '60-69', '40-49', '>=70', '<40', 'all']; 
 

 
array.sort(function (a, b) { 
 
    function getV(v) { return v.match(/\d+/g) || [Infinity, Infinity]; } 
 
    var aa = getV(a), 
 
     bb = getV(b); 
 

 
    return aa[0] - bb[0] || (aa[1] || aa[0]) - (bb[1] || bb[0]); 
 
}); 
 

 
console.log(array)

+0

Was ist, wenn eines der Elemente in deinem 'return' null ist? –

+0

können Sie einen Standardwert hinzufügen, wie 'return (aa [0] || 0) - (bb [0] || 0) || (aa [1] || aa [0] || 0) - (bb [1] || bb [0] || 0); ' –

+0

' Typfehler: bb ist null'. PS: Siehe meine Antwort für ein funktionierendes Modell –

Verwandte Themen