Page 1 of 1
Sorting numbers and text together
Posted: Sun Dec 29, 2013 11:09 am
by spacewalker
Hello,
I need to sort a text that contains leading numbers.
One problem is that the "numbers" may or may not have padded, leading zeros or an empty string..
So for example I have an array with strings like this
Code: Select all
a$(0) = "100,test1.txt"
a$(1) = "10 test2.txt"
a$(2) = "200test3.txt"
a$(3) = "20 test4.txt" ;tabulator
If I sort this using sortArray I get this:
Code: Select all
a$(0) = "10 test2.txt"
a$(1) = "100,test1.txt"
a$(2) = "20 test4.txt"
a$(3) = "200test3.txt"
However I would like to sort by the leading numbers' value so the result should be:
Code: Select all
a$(0) = "10 test2.txt"
a$(1) = "20 test4.txt"
a$(2) = "100,test1.txt"
a$(3) = "200test3.txt"
I am thinking to use a second "helper" array b() that contains the numbers for the actual sorting and then sort a$() somehow "synchronously" :
Code: Select all
a$(0) = "100,test1.txt"
a$(1) = "10 test2.txt"
a$(2) = "200test3.txt"
a$(3) = "20 test4.txt" ;tabulator
b(0) = 100
b(1) = 10
b(2) = 200
b(3) = 20
Now I can sort b() using SortArray() - but how would I sort a$() accordingly?
thanks
Re: Sorting numbers and text together
Posted: Sun Dec 29, 2013 11:49 am
by Little John
Hi,
the easiest way is to create a corresponding structure, and the use
SortStructuredArray:
Code: Select all
EnableExplicit
Macro SortStrucArray (_ArrayName_, _Options_, _Structure_Field_)
; This macro simplifies usage of the built-in function SortStructuredArray().
SortStructuredArray(_ArrayName_, _Options_, OffsetOf(_Structure_Field_), TypeOf(_Structure_Field_))
EndMacro
Structure MySortStruc
text$
value.i
EndStructure
Define i.i, lastElement.i=3
Dim a.MySortStruc(lastElement)
a(0)\text$ = "100,test1.txt"
a(1)\text$ = "10 test2.txt"
a(2)\text$ = "200test3.txt"
a(3)\text$ = "20 test4.txt"
For i = 0 To lastElement
a(i)\value = Val(a(i)\text$)
Next
SortStrucArray(a(), #PB_Sort_Ascending, MySortStruc\value)
For i = 0 To lastElement
Debug a(i)\text$
Next
Re: Sorting numbers and text together
Posted: Sun Dec 29, 2013 12:20 pm
by PB
> I would like to sort by the leading numbers' value
Just posted a nice procedure for you here:
http://www.purebasic.fr/english/viewtop ... 40&t=57819

Re: Sorting numbers and text together
Posted: Sun Dec 29, 2013 3:24 pm
by spacewalker
Little John wrote:Hi,
the easiest way is to create a corresponding structure, and the use SortStructuredArray:
thank you,that works
@PB:
Thank you fo your answer.
As you said, your code is OK for small arrays..but slow for large arrays.
Here is my procedure based on Little John's code. It sorts 1 million lines in 10 seconds or so:
Code: Select all
EnableExplicit
Procedure ArraySort_Numericstring( array output.s(1) )
Structure MySortStruct
text.s
value.l
EndStructure
Macro SortStrucArray (_ArrayName_, _Options_, _Structure_Field_)
; This macro simplifies usage of the built-in function SortStructuredArray().
SortStructuredArray(_ArrayName_, _Options_, OffsetOf(_Structure_Field_), TypeOf(_Structure_Field_))
EndMacro
Protected i.l
Protected lastElement.l = ArraySize (output() )
protected Dim a.MySortStruct(lastElement) ;helper structure
For i = 0 To lastElement
a(i)\text = output (i)
a(i)\value = val ( output (i)) ;Val (a(i)\text ) faster ?
next
SortStrucArray(a(), #PB_Sort_Ascending, MySortStruct\value)
for i=0 to LastElement
output (i) = a(i)\text
next
EndProcedure
dim output.s(1000000)
define i.l
;simulate array with 1 million elements
for i=0 to 1000000
output(i) = str (Random(1000000)) + " .Line xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
next
For i = 0 To 20 ;the first lines before sorting
Debug output(i)
Next
debug "------------------------------------------"
;sort them
ArraySort_Numericstring (output())
;result
For i = 0 To 20 ;the first lines after sorting
Debug output(i)
Next
thanks for your answers
Re: Sorting numbers and text together
Posted: Sun Dec 29, 2013 4:17 pm
by wilbert
This should be a bit faster
Code: Select all
Procedure SortNumericStrings(Array ArrayToSort.s(1))
Structure SortNumericStrings
value.i
*string
EndStructure
Protected *tmp.Integer, i.i, arraySize.i = ArraySize(ArrayToSort())
Dim tmp.SortNumericStrings(arraySize)
For i = 0 To arraySize
tmp(i)\value = Val(ArrayToSort(i))
tmp(i)\string = @ArrayToSort(i)
Next
SortStructuredArray(tmp(), #PB_Sort_Ascending, 0, #PB_Integer)
*tmp = @ArrayToSort()
For i = 0 To arraySize
*tmp\i = tmp(i)\string
*tmp + SizeOf(Integer)
Next
EndProcedure
Re: Sorting numbers and text together
Posted: Sun Dec 29, 2013 4:43 pm
by spacewalker
wilbert wrote:This should be a bit faster
very nice... according to my tests it's 10x faster
thank you