First of all I'm a newbie on oo programming, please have that in mind if you want to comment my effort below. I have written a sort class which will use chained comparators (up to 9 sortkeys possible ) I would like some feedback on: What I should have been done different or simpler. I also need some suggestion on the method names, that will get datainput, should have. For now I use these names: These two methods will return the sorted fields index in the original array Method build (works the same as Method lines) Method lines Method append (will return an new array when sort is finnished) All feedback is welcome and explain so also unexperienced and not native english speaking oo programmer understand. Thanks Håkan ----------------------------------------------------------------- /* Say "USEAGE:" Say "Upto 9 sortfields (sortkeys) can be specified Say "Setup sortcolumns start,length,(A)sc/(D)esc,(C)ase dependent, caseless if empty, default is caseless" Say "sortrecords = .Sortrecord~new()" Say "sortfields = .array~new" say "sortfields~append('20,8') most significant (ascending and caseless used as default)" say "sortfields~append('9,8,d') second most significant (caseless as deafult)" SAY "sortfields~append('1,8,A,c') third most significany ascending and casesensitive" SAY " Note all sortfields that pass test as being numeric is compared as numeric " say " " say "Sortrecords~Sortfields(sortfields) -- send over the sortfields" say Say "Feed array to sort with sortrecords~lines or ~build (works the same)" say " " SAY "do item over array if using a sparse array record index must be supplied" SAY " Sortrecord~build(item) ~build(item,array~index(item)) very slow on big arrays" Say "end " Say " " Say "-- Sort will return the record nr, fetch record with array~at(seq) " Say "do seq over Sortrecords~sort -- Sortrecords~stablesort also available" Say " say array~at(seq)" Say "end" Alternate is to ask to get an complete new array back (will solve sparse arrays problem) but will use more memory (1 copy of source array) But if the input is from a file directly feeded to sortrecords there is only one copy Do item over array or do until f~lines() = 0 sortrecord~append(item) sortrecord~append(f~linein) end end sortrecord~sort sortrecord~stablesort do item over sortrecord do item over sortrecord ? whatever ? whatever end end **/ /* Manage ca 150000 records with 3 sortfields(13 char total length), but actual datalength of the records can be bigger as this only build what is needed for sorting, returned is the index in original array Manage > 150000 records occasionally, running sortprogram twice in a row sometimes the intepreter crash, sometimes interpreter just sits there(no CPU) and sometimes it works. This on windows 10 Intel i7 2.67 Ghz 16Gb memory and ooRexx 4.3.0, */ ::CLASS SortRecord public /***************************************************/ /* */ /***************************************************/ ::method init expose sortfields recid sortarray inrecords delim recid = 0 sortarray = .array~new(100000) inrecords = .array~new(100000) delim = '00'x self~wantArray = .false /***************************************************/ /* */ /***************************************************/ ::Method sortfields expose sortfields use strict arg sortfields /***************************************************/ /* */ /***************************************************/ ::Method build expose sortfields sortArray recid delim use strict arg inrec, rid='' self~lines(inrec,rid) /***************************************************/ /* */ /***************************************************/ ::Method lines expose sortfields sortArray recid delim use strict arg inrec, rid='' if rid = '' then recid +=1 else recid = rid sortstring = '' do sf over sortfields parse var sf fs ',' fe ',' . sortstring = sortstring ||inrec~substr(fs~abs,fe~abs,' ')~translate('01'x,'20'x) || delim -- '00'x end parse var sortstring k1 (delim) k2 (delim) k3 (delim) k4 (delim) k5 (delim) k6 (delim) k7 (delim) k8 (delim) k9 (delim) . Sortarray~append(.sortkeys~new(recid,k1,k2,k3,k4,k5,k6,k7,k8,k9)) /***************************************************/ /* */ /***************************************************/ ::Attribute wantArray ::Method append expose sortfields sortArray recid inrecords delim use strict arg inrec, rid='' inrecords~append(inrec) if \ self~wantArray then self~wantArray = .true self~lines(inrec,rid) /***************************************************/ /* */ /***************************************************/ ::Method Sortchain private expose sortarray inrecords sortfields delim chain kseq. = '' ci. = '' f. = '' do sf over sortfields parse var sf fs ',' fe ',' seq ',' CI . x = sortfields~index(sf) kseq.x = seq~translate ci.x = ci~translate f.x = fe end k1 = .Sortkey1~new(kseq.1,ci.1) k2 = .Sortkey2~new(kseq.2,ci.2) k3 = .Sortkey3~new(kseq.3,ci.3) k4 = .Sortkey4~new(kseq.4,ci.4) k5 = .Sortkey5~new(kseq.5,ci.5) k6 = .Sortkey6~new(kseq.6,ci.6) k7 = .Sortkey7~new(kseq.7,ci.7) k8 = .Sortkey8~new(kseq.8,ci.8) k9 = .Sortkey9~new(kseq.9,ci.9) chain7 = .chaincomparator~new(k8,k9) chain6 = .chaincomparator~new(k7,chain7) chain5 = .chaincomparator~new(k6,chain6) chain4 = .chaincomparator~new(k5,chain5) chain3 = .chaincomparator~new(k4,chain4) chain2 = .chaincomparator~new(k3,chain3) chain1 = .chaincomparator~new(k2,chain2) chain = .chaincomparator~new(k1,chain1) if sortfields~items = 1 then do --chain = .chaincomparator~new(k1,k1) chain = k1 end if sortfields~items = 2 then do chain = .chaincomparator~new(k1,k2) end if sortfields~items = 3 then do chain1 = .chaincomparator~new(k2,k3) end if sortfields~items = 4 then do chain2 = .chaincomparator~new(k3,k4) end if sortfields~items = 5 then do chain3 = .chaincomparator~new(k4,k5) end if sortfields~items = 6 then do chain4 = .chaincomparator~new(k5,k6) end if sortfields~items = 7 then do chain5 = .chaincomparator~new(k6,k7) end if sortfields~items = 8 then do chain6 = .chaincomparator~new(k7,k8) end if sortfields~items = 9 then do chain7 = .chaincomparator~new(k8,k9) end /***************************************************/ /* */ /***************************************************/ ::Method sort expose sortarray chain inrecords self~sortchain sortarray~sortwith(chain) if self~wantArray then do z = .array~new(sortarray~items) do item over sortarray z~append(inrecords~at(item)) end return z end return sortarray /***************************************************/ /* */ /***************************************************/ ::Method stablesort expose sortarray chain inrecords self~sortchain sortarray~stablesortwith(chain) if self~wantArray then do z = .array~new(sortarray~items) do item over sortarray z~append(inrecords~at(item)) end return z end return sortarray /***************************************************/ /* */ /***************************************************/ ::Class sortKeys private /***************************************************/ /* */ /***************************************************/ ::Method Init expose recid key1 key2 key3 key4 key5 key6 key7 key8 key9 use arg recid, key1='' , key2='' , key3='' , key4='' , key5='', key6='', key7='', key8='', key9='' ::Attribute key1 ::Attribute key2 ::Attribute key3 ::Attribute key4 ::Attribute key5 ::Attribute key6 ::Attribute key7 ::Attribute key8 ::Attribute key9 ::Attribute recid /***************************************************/ /* */ /***************************************************/ ::Method string expose recid return recid /***************************************************/ /* */ /***************************************************/ --Here is a simple one. --The two arguments are comparators that determine how to compare the primary and secondary fields. --The secondary, of course, can be another chain comparator if you wish to go deeper. --Thanks to Rick McGuire on REXXLA list 23 jan 2014 -- For CLASS chaincomparator ::class chaincomparator private /***************************************************/ /* */ /***************************************************/ ::method init expose primary secondary use strict arg primary, secondary /***************************************************/ /* */ /***************************************************/ ::method compare expose primary secondary use strict arg first, second res = primary~compare(first, second) if res = 0 then res = secondary~compare(first, second) return res -- Ricks code stops here -- /***************************************************/ /* */ /***************************************************/ ::CLASS SortKey1 MIXINCLASS 'Comparator' private ::ATTRIBUTE sort ::Attribute case /***************************************************/ /* */ /***************************************************/ ::Method init expose sort case use arg seq, ci ='I' sort = 1 case = .false if seq~translate = 'D' then sort = -1 if ci~translate = 'C' then case = .true /***************************************************/ /* */ /***************************************************/ ::METHOD compare expose sort case use strict arg left, right if left~key1~datatype('N') & right~key1~datatype('N') then return sort*(left~key1-right~key1)~sign if case then return sort*left~key1~compareTo(right~key1) else return sort*left~key1~caselesscompareTo(right~key1) /***************************************************/ /* */ /***************************************************/ ::CLASS SortKey2 MIXINCLASS 'Comparator' private ::ATTRIBUTE sort ::Attribute case /***************************************************/ /* */ /***************************************************/ ::Method init expose sort case use arg seq, ci ='I' sort = 1 case = .false if seq~translate = 'D' then sort = -1 if ci~translate = 'C' then case = .true /***************************************************/ /* */ /***************************************************/ ::METHOD compare expose sort case use strict arg left, right if left~key2~datatype('N') & right~key2~datatype('N') then return sort*(left~key2-right~key2)~sign if case then return sort*left~key2~compareTo(right~key2) else return sort*left~key2~caselesscompareTo(right~key2) /***************************************************/ /* */ /***************************************************/ ::CLASS SortKey3 MIXINCLASS 'Comparator' private ::ATTRIBUTE sort ::Attribute case /***************************************************/ /* */ /***************************************************/ ::Method init expose sort case use arg seq, ci ='I' sort = 1 case = .false if seq~translate = 'D' then sort = -1 if ci~translate = 'C' then case = .true /***************************************************/ /* */ /***************************************************/ ::METHOD compare expose sort case use strict arg left, right if left~Key3~datatype('N') & right~Key3~datatype('N') then return sort*(left~Key3-right~Key3)~sign if case then return sort*left~Key3~compareTo(right~Key3) else return sort*left~Key3~caselesscompareTo(right~Key3) /***************************************************/ /* */ /***************************************************/ ::CLASS SortKey4 MIXINCLASS 'Comparator' private ::ATTRIBUTE sort ::Attribute case /***************************************************/ /* */ /***************************************************/ ::Method init expose sort case use arg seq, ci ='I' sort = 1 case = .false if seq~translate = 'D' then sort = -1 if ci~translate = 'C' then case = .true /***************************************************/ /* */ /***************************************************/ ::METHOD compare expose sort case use strict arg left, right if left~Key4~datatype('N') & right~Key4~datatype('N') then return sort*(left~Key4-right~Key4)~sign if case then return sort*left~Key4~compareTo(right~Key4) else return sort*left~Key4~caselesscompareTo(right~Key4) /***************************************************/ /* */ /***************************************************/ ::CLASS SortKey5 MIXINCLASS 'Comparator' private ::ATTRIBUTE sort ::Attribute case /***************************************************/ /* */ /***************************************************/ ::Method init expose sort case use arg seq, ci ='I' sort = 1 case = .false if seq~translate = 'D' then sort = -1 if ci~translate = 'C' then case = .true /***************************************************/ /* */ /***************************************************/ ::METHOD compare expose sort case use strict arg left, right if left~Key5~datatype('N') & right~Key5~datatype('N') then return sort*(left~Key5-right~Key5)~sign if case then return sort*left~Key5~compareTo(right~Key5) else return sort*left~Key5~caselesscompareTo(right~Key5) /***************************************************/ /* */ /***************************************************/ ::CLASS SortKey6 MIXINCLASS 'Comparator' private ::ATTRIBUTE sort ::Attribute case /***************************************************/ /* */ /***************************************************/ ::Method init expose sort case use arg seq, ci ='I' sort = 1 case = .false if seq~translate = 'D' then sort = -1 if ci~translate = 'C' then case = .true /***************************************************/ /* */ /***************************************************/ ::METHOD compare expose sort case use strict arg left, right if left~Key6~datatype('N') & right~Key6~datatype('N') then return sort*(left~Key6-right~Key6)~sign if case then return sort*left~Key6~compareTo(right~Key6) else return sort*left~Key6~caselesscompareTo(right~Key6) /***************************************************/ /* */ /***************************************************/ ::CLASS SortKey7 MIXINCLASS 'Comparator' private ::ATTRIBUTE sort ::Attribute case /***************************************************/ /* */ /***************************************************/ ::Method init expose sort case use arg seq, ci ='I' sort = 1 case = .false if seq~translate = 'D' then sort = -1 if ci~translate = 'C' then case = .true /***************************************************/ /* */ /***************************************************/ ::METHOD compare expose sort case use strict arg left, right if left~Key7~datatype('N') & right~Key7~datatype('N') then return sort*(left~Key7-right~Key7)~sign if case then return sort*left~Key7~compareTo(right~Key7) else return sort*left~Key7~caselesscompareTo(right~Key7) /***************************************************/ /* */ /***************************************************/ ::CLASS SortKey8 MIXINCLASS 'Comparator' private ::ATTRIBUTE sort ::Attribute case /***************************************************/ /* */ /***************************************************/ ::Method init expose sort case use arg seq, ci ='I' sort = 1 case = .false if seq~translate = 'D' then sort = -1 if ci~translate = 'C' then case = .true /***************************************************/ /* */ /***************************************************/ ::METHOD compare expose sort case use strict arg left, right if left~Key8~datatype('N') & right~Key8~datatype('N') then return sort*(left~Key8-right~Key8)~sign if case then return sort*left~Key8~compareTo(right~Key8) else return sort*left~Key8~caselesscompareTo(right~Key8) /***************************************************/ /* */ /***************************************************/ ::CLASS SortKey9 MIXINCLASS 'Comparator' private ::ATTRIBUTE sort ::Attribute case /***************************************************/ /* */ /***************************************************/ ::Method init expose sort case use arg seq, ci ='I' sort = 1 case = .false if seq~translate = 'D' then sort = -1 if ci~translate = 'C' then case = .true /***************************************************/ /* */ /***************************************************/ ::METHOD compare expose sort case use strict arg left, right if left~Key9~datatype('N') & right~Key9~datatype('N') then return sort*(left~Key9-right~Key9)~sign if case then return sort*left~Key9~compareTo(right~Key9) else return sort*left~Key9~caselesscompareTo(right~Key9)
------------------------------------------------------------------------------
_______________________________________________ Oorexx-users mailing list Oorexx-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/oorexx-users