[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Looping through an array with FOR EACH
[Thread Prev] | [Thread Next]
- Subject: Re: Looping through an array with FOR EACH
- From: Brian G <brian@xxxxxxxxxxxxxxxx>
- Date: Sun, 18 Jan 2026 15:17:25 -0800
- To: user@xxxxxxxxxxxxxxxxxxxxxx
Maybe I don't understand, but sorting and iterating the sorted array, now that Ben explained
Just cat the cols at fixed size to the keys eg key = colA&Colb&colC etc
order the cols as the sort requires. Good for single pass type sorts.
#!/usr/bin/env gbs3
dim a as new collection
for i as integer = 0 to 100
dim actualkey as string = "Item "&format(i,"###0")
dim col1 as string = str(format(rand(500),"00000000"))
dim col2 as string = str(format(rand(500),"00000000"))
dim col3 as string = str(format(rand(500),"00000000"))
dim key as string = col1&col2&col3
a.add([col1,col2,col3, ActualKey],key)
next
dim keys as string[] = a.keys.sort(gb.Ascent) ' or gb.descent
dim bsorted as new collection
for each s as string in keys
bsorted.add(a[s].extract(0,a[s].max),a[s].last)
next
'now print sorted collection
for each sa as string[] in bsorted
print bsorted.key,"";;"=[";;sa.join(",");;"]"
next
Quit 0
Catch
error "Script Error >";;error.text & "\n" & error.where
On 1/17/26 08:45, Manu wrote:
helloOrder in associative array, i.e. collection, is relative. So collection[].sort is relative.a/ order by reference, i.e. key b/ order by value, but it depends which data type is used. c/ order by recording, is just cosmetic, but not really useful.A good execise, import a CSV file (coma separate value) and convert to collection[]You notice how to import ( Excell, Libreoffice, ..., wants to know ! ). It expects a formula, a schema to import.One line is a collection. One data is a cell of column. One column expects a datatype.Imagine gridview with only collection[] Now, SQL is forbidden.Now , you must sort your collection[] using i.e. this column, after this other column, this ...Try to find the best way to sort. And finally, write a recursive function if you can. Complete Gridview to sort anything. example.csv --> collection[] id:author:title:category:qty:price:delivery:schedule22:Enid Mary Blyton:Oui-Oui et la Carte au trésor:ENFANTS:12:3.56:15/12/2022:"5:24"13:Zitrou:Ducobu plouf:BD:113:8.56:15/12/2022:"12:30"0:Enid Mary Blyton:Oui-Oui et Madame Ouistiti:ENFANTS:6:4.57:27/07/2022:"01:00".... Public Struct AVar 'DType 4 int 9 str 7 float 8 Date/Time 12 variant 'Data As Array ColumnKey As String Order As Integer A As Array AT As Integer 'type Array End Struct Public Struct Order Elem[4] As Struct AVar End Struct Private SK As New Order 'Sort Order by ColumnKey Public Sub Main() Dim t As Collection[] System.Language = "fr_FR.utf8" 'useful for date[] With SK.Elem[0] .ColumnKey = "category" .AT = 9 .Order = gb.Descent End With With SK.Elem[1] .ColumnKey = "author" .AT = 9 End With With SK.Elem[2] .ColumnKey = "qty" .AT = 4 .Order = gb.Descent End With With SK.Elem[3] .ColumnKey = "delivery" .AT = 8 End With t = SortByType4(3, "commandes.csv") ' 0->3 'CheckHorizontal(t) 'Check(t) SaveCsv("/tmp/foo.csv", t)'old syntax SortByType("commandes.csv", 9, "author", 7, "price", 9, "title")'old syntax SortByType2("commandes.csv") End Public Function Csv2Ac(FileCsv As String) As Collection[] Dim t As New Collection[], c As CsvFile c = New CsvFile(FileCsv, ":") 'ok c = CsvFile.Open(FileCsv, ",") While Not c.Eof t.Add(c.Read()) Wend Return t End Public Function SaveCsv(FileCsv As String, tb As Collection[]) Print "SaveCsv" Dim g As Collection Dim c As CsvFile c = CsvFile.Create(FileCsv, ",") g = tb[0] c.Fields = g.keys For i As Integer = 0 To tb.Max g = tb[i] 'For Each item As Variant In g ' Print g.key, ":", item 'Next c.Write(g) Next c.Close() End Private Sub InitA(k As Integer, table As Collection[]) 'Initialize & populate SK, k is skIndex Dim tmp As Object, g As Collection If k > 3 Then Error.Raise("InitA: 0,1,2,3 only") If Not SK.Elem[k].AT Then Error.Raise("InitA: DataType ??") 'Dim k As Integer = 0 Select Case SK.Elem[k].AT Case 1 tmp = New Boolean[] Print "DIM 1" Case 4 tmp = New Integer[] Print "DIM 4" Case 9 tmp = New String[] Print "DIM 9" Case 7 tmp = New Float[] Print "DIM 7" Case 8 tmp = New Date[] Print "DIM 8" ' TypeDate= date,date+time,time Default tmp = New String[] Print "DIM ELSE" End Select Print "typeOf tmp", TypeOf(tmp), "SK.Typeof", SK.Elem[k].AT, "K", k For i As Integer = 0 To table.max g = table[i] If g.Exist(SK.Elem[k].ColumnKey) Then If SK.Elem[k].AT = 8 Then tmp.Add(Val(g[SK.Elem[k].ColumnKey])) Else tmp.Add(g[SK.Elem[k].ColumnKey]) Endif Endif Next If Not SK.Elem[k].Order Then SK.Elem[k].Order = gb.Ascent SK.Elem[k].A = tmp Debug "check SK.Elem[k].A.Max", k, SK.Elem[k].A.Max EndPublic Function SortByType4(Deep As Integer, FileCsv As String) As Collection[]If Deep > 3 Then Error.Raise("Sort:Deep:0,1,2,3max") Dim table As Collection[], k As Integer = 0, skIndex As Integer = 0 table = Csv2Ac(FileCsv) Repeat InitA(skIndex, table) If skIndex = 0 Then For i As Integer = 0 To (SK.Elem[k].A.Max - 1) For j As Integer = i + 1 To SK.Elem[k].A.Max If SK.Elem[k].Order = gb.Ascent Then If SK.Elem[k].A[i] > SK.Elem[k].A[j] Then Print "0++\t\tswap", SK.Elem[k].A[i], SK.Elem[k].A[j] Swap SK.Elem[k].A[i], SK.Elem[k].A[j] Swap table[i], table[j] Endif Endif If SK.Elem[k].Order = gb.Descent Then If SK.Elem[k].A[i] < SK.Elem[k].A[j] Then Print "0--\t\tswap", SK.Elem[k].A[i], SK.Elem[k].A[j] Swap SK.Elem[k].A[i], SK.Elem[k].A[j] Swap table[i], table[j] Endif Endif Next Next 'If sk = Deep Then Return table Endif If skIndex = 1 Then For i As Integer = 0 To (SK.Elem[k].A.Max - 1) For j As Integer = i + 1 To SK.Elem[k].A.Max If SK.Elem[k].A[i] = SK.Elem[k].A[j] Then Debug "====", SK.Elem[k].A[i], SK.Elem[k].A[j] If SK.Elem[k + 1].Order = gb.Ascent Then If SK.Elem[k + 1].A[i] > SK.Elem[k + 1].A[j] ThenPrint "1++\t\tswap", SK.Elem[k + 1].A[i], SK.Elem[k + 1].A[j]Swap SK.Elem[k + 1].A[i], SK.Elem[k + 1].A[j] Swap table[i], table[j] Endif Endif If SK.Elem[k + 1].Order = gb.Descent Then If SK.Elem[k + 1].A[i] < SK.Elem[k + 1].A[j] ThenPrint "1--\t\tswap", SK.Elem[k + 1].A[i], SK.Elem[k + 1].A[j]Swap SK.Elem[k + 1].A[i], SK.Elem[k + 1].A[j] Swap table[i], table[j] Endif Endif Endif Next Next 'If sk = Deep Then Return table Endif If skIndex = 2 Then For i As Integer = 0 To (SK.Elem[k].A.Max - 1) For j As Integer = i + 1 To SK.Elem[k].A.MaxIf (SK.Elem[k].A[i] = SK.Elem[k].A[j]) And (SK.Elem[k + 1].A[i] = SK.Elem[k + 1].A[j]) Then Debug "====", SK.Elem[k].A[i], SK.Elem[k].A[j], SK.Elem[k + 1].A[i], SK.Elem[k + 1].A[j]If SK.Elem[k + 2].Order = gb.Ascent Then If SK.Elem[k + 2].A[i] > SK.Elem[k + 2].A[j] ThenPrint "2++\t\tswap", SK.Elem[k + 2].A[i], SK.Elem[k + 2].A[j]Swap SK.Elem[k + 2].A[i], SK.Elem[k + 2].A[j] Swap table[i], table[j] Endif Endif If SK.Elem[k + 2].Order = gb.Descent Then If SK.Elem[k + 2].A[i] < SK.Elem[k + 2].A[j] ThenPrint "2--\t\tswap", SK.Elem[k + 2].A[i], SK.Elem[k + 2].A[j]Swap SK.Elem[k + 2].A[i], SK.Elem[k + 2].A[j] Swap table[i], table[j] Endif Endif Endif Next Next 'If sk = Deep Then Return table Endif If skIndex = 3 Then For i As Integer = 0 To (SK.Elem[k].A.Max - 1) For j As Integer = i + 1 To SK.Elem[k].A.MaxIf (SK.Elem[k].A[i] = SK.Elem[k].A[j]) And (SK.Elem[k + 1].A[i] = SK.Elem[k + 1].A[j]) And (SK.Elem[k + 2].A[i] = SK.Elem[k + 2].A[j]) Then Debug "====", SK.Elem[k].A[i], SK.Elem[k].A[j], SK.Elem[k + 1].A[i], SK.Elem[k + 1].A[j], SK.Elem[k + 2].A[i], SK.Elem[k + 2].A[j]If SK.Elem[k + 3].Order = gb.Ascent Then If SK.Elem[k + 3].A[i] > SK.Elem[k + 3].A[j] ThenPrint "3++\t\tswap", SK.Elem[k + 3].A[i], SK.Elem[k + 3].A[j]Swap SK.Elem[k + 3].A[i], SK.Elem[k + 3].A[j] Swap table[i], table[j] Endif Endif If SK.Elem[k + 3].Order = gb.Descent Then If SK.Elem[k + 3].A[i] < SK.Elem[k + 3].A[j] ThenPrint "3--\t\tswap", SK.Elem[k + 3].A[i], SK.Elem[k + 3].A[j]Swap SK.Elem[k + 3].A[i], SK.Elem[k + 3].A[j] Swap table[i], table[j] Endif Endif Endif Next Next 'If sk = Deep Then Return table Endif If skIndex = Deep Then Return table Inc skIndex 'Print "skIndex", skIndex Until skIndex > Deep End Le 17/01/2026 à 17:07, Gianluigi a écrit :Il 17/01/26 16:15, Benoît Minisini ha scritto:Le 17/01/2026 à 15:19, Gianluigi a écrit :Il 17/01/26 14:48, Benoît Minisini ha scritto:No. As I explaines, the order comes from a specific feature added to the hash table. This feature is not mandatory for a hash table to be a hash table. I added it because it allows to use the hash table both as a hash table and a rudimentory ordered list. But it has a cost: 16 bytes by element!Hi Benoit,I apologize, but as I told Jussi, I'm working on another job and I didn't explain myself well. Let me put it this way: if someone asks me if the Gambas3 collections are in order and I say yes, am I wrong?No. It's just that it is not "officially" guaranteed yet, even if I won't change that now, and if I want an unordered Collection, I will create another class.I'm ignorant, I haven't studied math, and I don't know hash tables, so I can't talk about them.This is not math, this is algorithms. A hash table is an array.But to be able to use indexes that are strings for storing an element, the string is transformed (we say "hashed", hence the name "hash table") into an integer lower than the size of the array, that is the index in that array where we want to store the element.Then, as two strings may lead to the same index, we actually store another array in each element of the initial array. It's that second- level array that stores all elements of the hash table whose string key lead to same index.Then things become a bit complex, because when you add more elements to the hash table (or remove them), it adapts the size of its first-level array and reorganizes everything so that there is not too many string keys leading to the same index, for performance reasons.I don't know if it's clear for you. You will find for sure better explanations on the Internet with good examples.Regards,Dear Benoit, great, I finally figured out what these damn hash tables are.Now I can confess, I'd read about them several times, and I never understood anything. You were really kind to clarify things for me; I never understood what collisions meant.I swore to myself I'd never bother you again, but now I'm glad I did.I can't tell you I love you because I already made that declaration to Fabien Bodard, but now my heart is undecided. 😍 🙂Thanks again and best regards Gianluigi
-- ~~~~ Brian
Attachment:
OpenPGP_0x78BFB26402F48419.asc
Description: OpenPGP public key
Attachment:
OpenPGP_signature.asc
Description: OpenPGP digital signature