@@ -0,0 +1,197 @@
const Sorter = function ( arr = [ ] , key = null , def = null ) {
state = {
arr,
key,
def
}
const proto = {
type : 'Sorter' ,
swap ( arr , left , right ) {
let temp = arr [ left ] ;
arr [ left ] = arr [ right ] ;
arr [ right ] = temp ;
} ,
partition ( arr , start , finish ) {
let partitionIndex = finish ;
let partitionValue = arr [ partitionIndex ] ;
let i = start ;
let j = finish ;
for ( i ; i < j ; i ++ ) {
if ( arr [ i ] > partitionValue ) {
this . swap ( arr , i , partitionIndex ) ;
partitionIndex = i ;
partitionValue = arr [ i ] ;
for ( j ; j > i ; j -- ) {
if ( arr [ j ] < partitionValue ) {
this . swap ( arr , j , partitionIndex ) ;
partitionIndex = j ;
partitionValue = arr [ j ] ;
break ;
}
}
}
}
return ( partitionIndex ) ;
} ,
separate ( arr ) {
let divider ;
let i ;
let n = arr . length - 1 ;
let temp ;
for ( i = 0 ; i < arr . length ; i ++ ) {
if ( i === n ) {
divider = i ;
return [ arr , i ] ;
}
if ( typeof ( arr [ i ] ) === 'string' ) {
for ( n ; n >= i ; n -- ) {
if ( typeof ( arr [ n ] ) === 'number' ) {
temp = arr [ i ] ;
arr [ i ] = arr [ n ] ;
arr [ n ] = temp ;
break ;
}
}
}
}
}
}
const setAndGet = {
setArray ( arr = null ) {
if ( ! arr || ! Array . isArray ( arr ) ) {
console . log ( 'setArray must be called with an array of values' ) ;
return ;
}
state . arr = arr ;
} ,
setKey ( key = null ) {
if ( ! key || typeOf ( key ) === 'object' ) {
console . log ( 'setKey must be called with a non-object' ) ;
return ;
}
state . key = key ;
} ,
setDef ( def = null ) {
if ( def && ! typeof ( def ) === 'function' ) {
console . log ( 'setDef must be called with a function or nothing at all' ) ;
return ;
}
state . def = def ;
} ,
getArray ( ) {
return state . arr ;
} ,
getKey ( ) {
return state . key ;
} ,
getDef ( ) {
return state . def ;
}
} ;
const sorting = {
strSort ( arr ) {
if ( arr && ! Array . isArray ( arr ) ) {
console . log ( 'stringSort must be called with an array' ) ;
return ;
}
if ( ! arr && ! state . arr ) {
console . log ( 'No array to sort!' ) ;
return ;
}
const theArr = ( ! arr ) ? SortedArray ( state . arr . slice ( ) ) : arr ;
return ( ! state . def ) ? theArr . sort ( ) : theArr . sort ( state . def ) ;
} ,
numSort ( arr ) {
if ( arr && ! Array . isArray ( arr ) ) {
console . log ( 'numSort must be called with an array' ) ;
return ;
}
if ( ! arr && ! state . arr ) {
console . log ( 'No array to sort!' ) ;
return ;
}
const sortFunc = state . def || ( ( a , b ) => { return ( a < b ) ? - 1 : 1 } ) ;
return ( ! arr ) ? state . arr . slice ( ) . sort ( sortFunc ) : arr . sort ( sortFunc ) ;
} ,
mixSort ( arr ) {
if ( arr && ! Array . isArray ( arr ) ) {
console . log ( 'mixSort must be called with an array' ) ;
return ;
}
if ( ! arr && ! state . arr ) {
console . log ( 'No array to sort!' ) ;
return ;
}
let theArr = ( ! arr ) ? this . separate ( this . state . arr . slice ( ) ) : this . separate ( arr ) ;
console . log ( theArr ) ;
let numbers = theArr [ 0 ] . slice ( 0 , theArr [ 1 ] ) ;
let strings = theArr [ 0 ] . slice ( theArr [ 1 ] ) ;
this . quickSort ( numbers ) ;
this . quickSort ( strings ) ;
return numbers . concat ( strings ) ;
} ,
quickSort ( arr , start = 0 , finish = arr . length - 1 ) {
if ( start < finish ) {
index = this . partition ( arr , start , finish ) ;
this . quickSort ( arr , start , index - 1 ) ;
this . quickSort ( arr , index + 1 , finish ) ;
}
return arr ;
}
}
const SortedArray = ( arr ) => {
return Object . assign ( Object . create ( arr ) , sorting ) ;
}
return Object . assign ( Object . create ( proto ) , setAndGet , sorting ) ;
}
/ *
const mySort = Sorter ( ) ;
let numArray = [ 80 , 2323 , 'zebra' , 43 , 'cause' , 334 , 23232 , 80 , 2323 , 'zebra' , 43 , 'cause' , 334 , 23232 ] ;
mySort . setArray ( numArray ) ;
console . log ( mySort . mixSort ( numArray ) ) ; // [43, 43, 80, 80, 334, 334, 2323, 2323, 23232, 23232, "cause", "cause", "zebra", "zebra"]