@@ -538,7 +538,7 @@ namespace ts {
538538 */
539539 export function append < T > ( to : T [ ] | undefined , value : T | undefined ) : T [ ] | undefined {
540540 if ( value === undefined ) return to ;
541- if ( to === undefined ) to = [ ] ;
541+ if ( to === undefined ) return [ value ] ;
542542 to . push ( value ) ;
543543 return to ;
544544 }
@@ -559,6 +559,16 @@ namespace ts {
559559 return to ;
560560 }
561561
562+ /**
563+ * Stable sort of an array. Elements equal to each other maintain their relative position in the array.
564+ */
565+ export function stableSort < T > ( array : T [ ] , comparer : ( x : T , y : T ) => Comparison = compareValues ) {
566+ return array
567+ . map ( ( _ , i ) => i ) // create array of indices
568+ . sort ( ( x , y ) => comparer ( array [ x ] , array [ y ] ) || compareValues ( x , y ) ) // sort indices by value then position
569+ . map ( i => array [ i ] ) ; // get sorted array
570+ }
571+
562572 export function rangeEquals < T > ( array1 : T [ ] , array2 : T [ ] , pos : number , end : number ) {
563573 while ( pos < end ) {
564574 if ( array1 [ pos ] !== array2 [ pos ] ) {
@@ -2022,6 +2032,17 @@ namespace ts {
20222032 }
20232033
20242034 /** Remove an item from an array, moving everything to its right one space left. */
2035+ export function orderedRemoveItem < T > ( array : T [ ] , item : T ) : boolean {
2036+ for ( let i = 0 ; i < array . length ; i ++ ) {
2037+ if ( array [ i ] === item ) {
2038+ orderedRemoveItemAt ( array , i ) ;
2039+ return true ;
2040+ }
2041+ }
2042+ return false ;
2043+ }
2044+
2045+ /** Remove an item by index from an array, moving everything to its right one space left. */
20252046 export function orderedRemoveItemAt < T > ( array : T [ ] , index : number ) : void {
20262047 // This seems to be faster than either `array.splice(i, 1)` or `array.copyWithin(i, i+ 1)`.
20272048 for ( let i = index ; i < array . length - 1 ; i ++ ) {
0 commit comments