Page 1 of 1

Sort a list alphanumerically

Posted: Tue Sep 26, 2023 9:05 pm
by Kurzer
Hi sorting experts,

this is my attempt to sort a list alphanumerically in ascending order.
Is there any way to tweak the code or do you think it fits as it is?

Thanks a lot for your feedback.

Code: Select all

NewList MyList.s()

AddElement(MyList()) : MyList() = "D"
AddElement(MyList()) : MyList() = "B"
AddElement(MyList()) : MyList() = "C"
AddElement(MyList()) : MyList() = "A"
AddElement(MyList()) : MyList() = "F"
AddElement(MyList()) : MyList() = "E"

SearchStart = 0
SearchEnd = ListSize(MyList()) - 1


For i = SearchStart To SearchEnd - 1
	SelectElement(MyList(), i)
	*OuterEntry = @MyList()
	OuterValue.s = MyList()
	Debug "Reference (" + i + ") -> " + MyList()
	For j = i + 1 To SearchEnd
		SelectElement(MyList(), j)
		Debug "     Search (" + j + ") -> " + MyList()
		If MyList() < OuterValue
			Debug "Move " + MyList() + " before " + OuterValue + " and start the search again at the last reference entry."
			MoveElement(MyList(), #PB_List_Before, *OuterEntry)
			i = SearchStart - 1
			Break
		EndIf
		If j = SearchEnd And SearchStart < SearchEnd
			Debug "No need to move, continue the search with the next reference entry."
			SearchStart + 1
		EndIf
	Next
Next

ForEach MyList()
	Debug MyList()
Next

Re: Sort a list alphanumerically

Posted: Tue Sep 26, 2023 9:45 pm
by Kiffi
I'm not sure if I understood your request correctly, but why don't you use SortList()?

Code: Select all

NewList MyList.s()

AddElement(MyList()) : MyList() = "D"
AddElement(MyList()) : MyList() = "B"
AddElement(MyList()) : MyList() = "C"
AddElement(MyList()) : MyList() = "A"
AddElement(MyList()) : MyList() = "F"
AddElement(MyList()) : MyList() = "E"

SortList(MyList(), #PB_Sort_Ascending)

ForEach MyList()
  Debug MyList()
Next

Re: Sort a list alphanumerically

Posted: Tue Sep 26, 2023 11:04 pm
by Kurzer
Kiffi, thank you for your reply.

First, I didn't find SortList() in the list library...

Image

... and second, my posted source code is just an simplified example.

In the real use case, I want to sort a structured list where some entries are linked to a reference entry. The reference entries need to be sorted in the list before the entries that reference them.

I don't know if the (undocumented?) SortList() function can do this.

Edit:
Damn, okay found it in the sort library.

Image

I have to say in my defense that I've never needed this before. :-D

Re: Sort a list alphanumerically

Posted: Wed Sep 27, 2023 4:19 am
by Fangbeast
Kurzer, won't

Code: Select all

SortStructuredList(ListName(), Options, OffsetOf(Structure\Field), TypeOf(Structure\Field) [, Start, End])


do the job??? I searched PB help and found it without a problem.

Re: Sort a list alphanumerically

Posted: Wed Sep 27, 2023 7:33 am
by Kurzer
Fangbeast, thank you.

I must confess that I did not explicitly search for the term, but only looked in the List library command list. But I see now that SortList is also mentioned there. So, as is often the case, the "problem" is clearly the user sitting in front of the screen.

I'll have a look at it today to see if SortStructuredList() can do the job. The peculiarity is that you don't have to sort by a single field, but by the following scheme:

Field A -> Identifier of the entry
Field B -> Identifier ID of an entry to be referenced (can also be empty).

Example:

Code: Select all

A: 0 B: -
A: 1 B: 4
A: 2 B: 3
A: 3 B: 1
A: 4 B: -
Should look sorted like this:

Code: Select all

A: 0 B: -
A: 4 B: -
A: 1 B: 4
A: 3 B: 1
A: 2 B: 3

(in the real case the numbers are integer addresses, so much bigger numbers)

The logic now is to sort everything so that all entries that reference another entry are *after* the referenced element in the list. And there can be references to references to references to references.... etc., i.e. nested references.

I'll create an updated example and try to implement the sorting based on it.

The example in the first post I had only kept so simple because I did not have the Sort commands for lists in mind at the time. This "superficiality" is the price I have to pay, because due to my time management I can only work with Purebasic and projects program in a very fragmented way. The rest of the time I have completely different things in my head. I know this already, that's why I'm only moderately embarrassed by my posts of this kind. LOL :D


Edit:

This is the example code to get close to the real use case. I don't think you can get there with SortStructuredList() alone, but as I said, I'll take a closer look today.

Code: Select all

Structure MyStruct
	Entry.i
	RefEntry.i	
EndStructure

NewList StructList.MyStruct()

AddElement(StructList()) : StructList()\Entry = 1
AddElement(StructList()) : StructList()\Entry = 2 : StructList()\RefEntry =3
AddElement(StructList()) : StructList()\Entry = 3 : StructList()\RefEntry =6
AddElement(StructList()) : StructList()\Entry = 4
AddElement(StructList()) : StructList()\Entry = 5 : StructList()\RefEntry =2
AddElement(StructList()) : StructList()\Entry = 6

SortStructuredList(StructList(), #PB_Sort_Ascending, OffsetOf(MyStruct\RefEntry), TypeOf(MyStruct\RefEntry))

ForEach StructList()
	Debug "Entry: " + Str(StructList()\Entry) + " - Ref to: " + Str(StructList()\RefEntry)
Next

Re: Sort a list alphanumerically

Posted: Wed Sep 27, 2023 8:33 am
by Fred
I agree it's a bit weird to have a different sort library topics, it should be dispatched into Array and List IMHO

Re: Sort a list alphanumerically

Posted: Wed Sep 27, 2023 8:53 am
by Andre
Fred wrote: Wed Sep 27, 2023 8:33 am I agree it's a bit weird to have a different sort library topics, it should be dispatched into Array and List IMHO
Maybe true....

But at least in the 'Overview' of the library documentation it's clearly written which additional commands can be useful (including links to them).

For example in the 'List' docs:
Lists can be sorted using SortList() or SortStructuredList(), and can also be randomized using RandomizeList().
https://www.purebasic.com/documentation/list/index.html

There are mentioned other commands from other libraries too.

So I don't think there is a much better solution than now 8)

Re: Sort a list alphanumerically

Posted: Wed Sep 27, 2023 9:16 am
by Olli
kurzen wrote:I have to say in my defense that I've never needed this before.
He has stolen my best argument of defense. :mrgreen:

Re: Sort a list alphanumerically

Posted: Wed Sep 27, 2023 9:28 am
by Kurzer
Olli wrote: Wed Sep 27, 2023 9:16 am He has stolen my best argument of defense. :mrgreen:
Don't worry, Olli, this argument can be used multiple times.

@Fred and @Andre, you're both kind of right. In the end, I didn't look for it enough (although it should have caught my eye right away).

Re: Sort a list alphanumerically

Posted: Wed Sep 27, 2023 9:30 am
by the.weavster
You could always consider using an in-memory sqlite database as an alternative to maps and structures if your sorting needs are complex.

Re: Sort a list alphanumerically

Posted: Wed Sep 27, 2023 10:04 am
by Kurzer
This is probably a bit "overloaded" in this case, because it is about sorting of gadgets of a window, which are managed in a list.
So there probably won't be hundreds of thousands of entries, rather only 2 - 40, depending on the complexity of the window.
Finally, you can write your own short sorting procedure for this.

Re: Sort a list alphanumerically

Posted: Wed Sep 27, 2023 3:30 pm
by skywalk
When I require a complex and stable sort, I use qsort() with a custom callback.

Re: Sort a list alphanumerically

Posted: Wed Sep 27, 2023 5:16 pm
by vmars316
SortList(WordsList(),#PB_Sort_Ascending | #PB_Sort_NoCase)

Re: Sort a list alphanumerically

Posted: Wed Sep 27, 2023 7:51 pm
by AZJIO
Andre wrote: Wed Sep 27, 2023 8:53 am So I don't think there is a much better solution than now
I also didn’t immediately find the sorting functions, since I always look at the list. You can duplicate it in the tree and on the page where the list of functions is. In this case, you don’t have to remove the “sorting” section. The functions found there are not general enough to be separated into a separate section. That is, sorting a list is only for a list, sorting an array is only for an array. Therefore, it looks strange that some of the functions for the list are in a separate section. I would like NewList, NewMap, Dim to be duplicated in their sections despite the fact that this is a keyword, not a function. Very often, when I wanted to find NewList, I always went to the “List” section, then I remembered for a long time what this function was called and looked in my other sources. Then I discovered that on the section description page there are always links to these functions and it became easier for me.
By the way, many pages are missing from the tree; links to them can be found on other pages, but not in the tree. When I was looking for compiler parameters it was always a pain, I spent half an hour reading links on pages about compilation. In the end, I simply added all the keywords and all the missing pages to the tree myself and called them names that made sense to me.

My opinion is that the sorting section is not needed, but I do not suggest removing it, as opponents may appear. If the vast majority agrees, then there is no point in duplicating the section

You could do something like the example below, where the keywords are a continuation of the list, which pushes the user's eye to continue looking at the next related keywords.

Code: Select all

Command Index
    AddElement
    ...
    SwapElements

Keywords
    NewList
    ForEach : Next
Example
    ...

Re: Sort a list alphanumerically

Posted: Wed Sep 27, 2023 8:37 pm
by Andre
Thank you for your suggestions, AZJIO. Good points :-)

All about the Help index / tree (made by the DocMaker tool) or removing / changing e.g. the Sort library and moving the commands to the List or Array commands is something for Fred.

For now I always tried to add as many as possible useful links to other related commands or keywords in the command description / library overview.
Something you already discovered in the meantime 8)