Array.SortRange()
BlitzMax Forums/BlitzMax Module Tweaks/Array.SortRange()
| ||
Hi, A small tweak so you can sort only part of an array. I find it useful, because it means you can pre-allocate a nice big array, even though you might not use all of it, and still sort it. Normally you have to slice the array to contain only valid elements (ie. no Null references), if you want to sort it. This gets around that nice and easily. The following changes are needed: In mod/brl.mod/blitz.mod/blitz_array.h, after the bbArraySort line for instance, add: void bbArraySortRange( BBArray *arr,int lo,int hi,int ascending );In mod/brl.mod/blitz.mod/blitz_array.c, after the bbArraySort line, add: bbArraySortRange, And at the end of the file add: void bbArraySortRange( BBArray *arr,int lo,int hi,int ascending ){ void *p; if( (hi-lo)<=0 ) return; p=BBARRAYDATA(arr,arr->dims); if( ascending ){ switch( arr->type[0] ){ case 'b':qsort_b( (unsigned char*)p+lo,(unsigned char*)p+hi );break; case 's':qsort_s( (unsigned short*)p+lo,(unsigned short*)p+hi );break; case 'i':qsort_i( (int*)p+lo,(int*)p+hi );break; case 'l':qsort_l( (BBInt64*)p+lo,(BBInt64*)p+hi );break; case 'f':qsort_f( (float*)p+lo,(float*)p+hi );break; case 'd':qsort_d( (double*)p+lo,(double*)p+hi );break; case '$':case ':':qsort_obj( (BBObject**)p+lo,(BBObject**)p+hi );break; } }else{ switch( arr->type[0] ){ case 'b':qsort_b_d( (unsigned char*)p+lo,(unsigned char*)p+hi );break; case 's':qsort_s_d( (unsigned short*)p+lo,(unsigned short*)p+hi );break; case 'i':qsort_i_d( (int*)p+lo,(int*)p+hi );break; case 'l':qsort_l_d( (BBInt64*)p+lo,(BBInt64*)p+hi );break; case 'f':qsort_f_d( (float*)p+lo,(float*)p+hi );break; case 'd':qsort_d_d( (double*)p+lo,(double*)p+hi );break; case '$':case ':':qsort_obj_d( (BBObject**)p+lo,(BBObject**)p+hi );break; } } }In mod/brl.mod/blitz_classes.i, after the -Sort( ... ) line (at the end of the file), add: -SortRange( lo:Int,hi:Int,ascending=1 )="bbArraySortRange"Now all you need to do is recompile your modules (Ctrl+D). You may need to modify blitz.mod in order for it to work, just open it, hit space somewhere and recompile the modules. Here's a small example of the use of SortRange() Local bob:Int[] = [9,8,7,6,5,4,3,2,1] bob.SortRange(0,5) For i = 0 Until bob.length Print bob[i] NextIt takes three parameters: lo = the first array index to start the sorting from hi = the last array index to include in the sort ascending = whether you want to sort hi->lo or lo->hi If you use it like this bob.SortRange(0,bob.length-1) it sorts the entire array, just like the regular Sort method. Here's a silly example showing how SortRange can come in handy: Strict Type whatever Field alpha Method compare:Int(other:Object) If Whatever(other) Return Sgn(alpha - Whatever(other).alpha) EndIf Return -1 EndMethod EndType Local bob:Whatever[8] For Local i:Int = 0 To 3 bob[i] = New Whatever bob[i].alpha = Rand(0,6) Next bob.SortRange(0,3) ' ' This wouldn't work because the array has Null references ' bob.Sort() For Local i:Int = 0 Until bob.length If bob[i] Print bob[i].alpha Else Print "Null" EndIf NextHope you have a use for it! |