you are correct, there is no .Set, thus the question, does .Put do as Set does.1. There is no .Set in KVS
2. I never know there is a 3 dimensional List. Do you mean a List "nested" inside another List?
It is better you can upload a small example to show the error so other members can help you.
B4X:newListVar = AP.get(1) 'to access Journals newListvar = newListVar.get(2) 'to access 3rd journal entry log(newListVar.get(2)) 'to access the actual text of the journal
Using KVS is like you do with Maps, but it persists to a file or reads from a file.you are correct, there is no .Set, thus the question, does .Put do as Set does.
And yes the term dimensional is the same as nested. It just indicates how many nests there are.
Sorry, I have no sample code as I am trying to figure this out. The only errors i get are Syntax errors as I type it.(see previous examples of datum extraction)
Ap is a list of lists, of lists, and yes, 0 to size - 1This should work, assuming that AP is a list of lists of lists of strings.
Remember that the index (key) starts at 0, not 1. If you only have a single item in a list, then .Get(1) will fail. Use .Get(0) to get the first item.
What does AP stand for? Is it an actual List? Is it stored in memory? What else is stored in it (besides journals)? (there must be something else in it, at AP.Get(0) ie the first list item)
It feels like you're using Lists to ask a question about accessing an online library or database.
Also, why is a journal entry a list of strings (text) rather than just a single string? For example, text files (eg readme.txt) are a single string, containg CRLFs to separate lines and sometimes FFs (ASCII 12 = printer formfeed control code) to separate pages.
I starting with a map. But regex'ing everything got discombobulating. KVS saves and retrieves as lists, even lists of lists. Trying to unMAP 3 dimensions, frankly, blew my mind to bits. As the individual entries are set in size, the data is different for all entries, some are editable some are not, so remaking the lists was a daunting task indeed.Using KVS is like you do with Maps, but it persists to a file or reads from a file.
Put
adds a new key and value when the key does not exist;
overwrites the value when the key already exist.
Get
reads the value by the key when the key exists;
returns null when the key does not exist.
Please read the B4X Language guide for Maps and List to understand how they works.
Maybe you should use a Map inside a List instead of using a List inside a List.
e.g
StudentList contains list [ {"name": "Alice", "age": 18}, {"name": "Bob", "age": 21} ]
how to access a datum three levels down in one line of code. In VB it was: myArray(2,4,3)
Sub myArray(A As Int, B As Int, C As Int) As Object
Return AP.Get(A).As(List).Get(B).As(List).Get(C)
End Sub
Dim Temp As String = myArray(2, 4, 3).As(String)
Sub myArray(A As Int, B As Int, C As Int) As String
Return AP.Get(A).As(List).Get(B).As(List).Get(C) 'don't need .As(String) since it will automatically be cast to the function's return type ie String
End Sub
Dim Temp As String = myArray(2, 4, 3)
Log( Return AP.Get(2).As(List).Get(4).As(List).Get(3).As(String).ToUpperCase )
chose not to MAP it as map stores as strings
You have said the .Put overwrites. I shall re-examine the code to make sure I am not corrupting the data. The keys are generated automatically when I hit the Save button to save a record. If the record was selected from an existing file, the key is extracted at that point and so does not need to be generated.To better help you. it is better you post a sample data showing the structure or format.
Put is overwriting the value if the key matched. If your code doesn't behave as this then there must be something wrong with your code.
journal entries, hours entries, financial entries
I apologize, I am not porting from VB, I was referring to the 90's when I was programming front end UIs for databanks. Multi dimension arrays are confusing and can be difficult to grasp visually. When I mention mArray(2,4,3) I don't mean a list containing a 2,a 4 & a 3. I mean a mutli-dimension array where that statement reads the third datum in the 2 array of the first array. And therein lies my conundrum. How do I do that in B4AIf they are lists of lists of lists, then one way of doing it would be via a helper function (which might also make porting from your VB code easier too):
B4X:Sub myArray(A As Int, B As Int, C As Int) As Object Return AP.Get(A).As(List).Get(B).As(List).Get(C) End Sub Dim Temp As String = myArray(2, 4, 3).As(String)
Or you could do it inline, eg:
B4X:Log( Return AP.Get(2).As(List).Get(4).As(List).Get(3).As(String).ToUpperCase )
where I've used .ToUpperCase as an excuse to demonstrate casting the unknown Object to a string with .As(String)
Maps and Lists store Objects, which can be Strings, but can also be anything else, including nested Maps and Lists.
' this is dummed down version. Please DO NOT get hung up on _
the syntax of how the data is getting into the lists
project_id_tag = "x9-ert-2025"
dim AllProjects as list
dim LiveProject as list
dim journal, hours, mtrls as list
'user would write in this data, but for the sample I am demonstrating the data structure it in
journal.Add ["04/07/2025", "08:00","Delivered material to job site"]
hours.Add ["04/07/2025","08:00","09:30",1.5,65,tax=True]
mtrls.Add ["04/07/2025","06:30","2x4s",36,5.99]
mtrls.Add ["04/07/2025", "11:15","3-1/2 nails",2,26.99]
hours.Add ["04/07/2025", "11:45", "12:15", .5, 65, tax=True]
LiveProject.add(journal)
LiveProject.add(hours)
LivePProject.add(mtrls)
AllProjects.Put(project_id_tag)
'please tell me what time the nails were purchased in one line of code
yes. not the best choice of words on my part. diary is probably a better term. In college we were taught to 'journal' the day, so it has stuck in my head. I have financial memos in the finances, not ledgers. Simple incoming and outgoing funds. Payments and refunds. Materials finance is handled elsewhereAh, I was thinking journal as in scientific magazine or collection of scientific papers.
And then: journal entry as in a note made into a diary history.
But journal ledger, as in a list of transactions not recorded in another financial ledger, works too.
Dim AP As List
AP.Initialize
Dim FirstList As List
FirstList.Initialize
AP.Add(FirstList)
Dim JournalLedger As List
JournalLedger.Initialize
AP.Add(JournalLedger)
Dim SampleJournalEntries() As String = Array As String( _
"Andy", "11/01/2025", 123.01, _
"Bobby", "19/02/2025", 456.02, _
"Charlie", "08/03/2025", 789.03, _
"Danny", "25/04/2025", 135.04, _
"Ernie", "17/05/2025", 246.05, _
"Freddy", "14/06/2025", 357.06 _
)
For I = 0 To SampleJournalEntries.Length - 1 Step 3
Dim JournalEntry As List
JournalEntry.Initialize
JournalEntry.Add(SampleJournalEntries(I + 0)) 'name
JournalEntry.Add(SampleJournalEntries(I + 1)) 'date
JournalEntry.Add(SampleJournalEntries(I + 2)) 'value
JournalLedger.Add(JournalEntry)
Next
Log("*** list of lists of lists ***")
Log(AP)
Log("*** journal entry lists ***")
For I = 0 To 5
Log(I & TAB & AP.Get(1).As(List).Get(I))
Next
Log("*** inline ***")
For I = 0 To 5
Log( _
I & TAB & _
AP.Get(1).As(List).Get(I).As(List).Get(0) & TAB & _
AP.Get(1).As(List).Get(I).As(List).Get(1) & TAB & _
AP.Get(1).As(List).Get(I).As(List).Get(2) _
)
Next
Log("*** step-by-step ***")
Dim JournalLedger As List = AP.Get(1)
For I = 0 To JournalLedger.Size - 1
Dim JournalEntry As List = JournalLedger.Get(I)
Dim JEName As String = JournalEntry.Get(0)
Dim JEDate As String = JournalEntry.Get(1)
Dim JEValue As String = JournalEntry.Get(2)
Log(I & TAB & JEName & TAB & JEDate & TAB & JEValue)
Next
Waiting for debugger to connect...
Program started.
*** list of lists of lists ***
(ArrayList) [[], [[Andy, 11/01/2025, 123.01], [Bobby, 19/02/2025, 456.02], [Charlie, 08/03/2025, 789.03], [Danny, 25/04/2025, 135.04], [Ernie, 17/05/2025, 246.05], [Freddy, 14/06/2025, 357.06]]]
*** journal entry lists ***
0 [Andy, 11/01/2025, 123.01]
1 [Bobby, 19/02/2025, 456.02]
2 [Charlie, 08/03/2025, 789.03]
3 [Danny, 25/04/2025, 135.04]
4 [Ernie, 17/05/2025, 246.05]
5 [Freddy, 14/06/2025, 357.06]
*** inline ***
0 Andy 11/01/2025 123.01
1 Bobby 19/02/2025 456.02
2 Charlie 08/03/2025 789.03
3 Danny 25/04/2025 135.04
4 Ernie 17/05/2025 246.05
5 Freddy 14/06/2025 357.06
*** step-by-step ***
0 Andy 11/01/2025 123.01
1 Bobby 19/02/2025 456.02
2 Charlie 08/03/2025 789.03
3 Danny 25/04/2025 135.04
4 Ernie 17/05/2025 246.05
5 Freddy 14/06/2025 357.06
cheated with gerry and jerry? George and jeremy? Gary and Jack. Gerard and James.Lol wonder how far that sequence could go:
Gerry, Harry, Iggy (Pop), Jerry, Kenny, Larry, Maurie, Nicky, Ollie, Percy, Quincy, Ricky, Sammy, Tommy, Uri (Geller), Vinny, Wally, Xi, Yogi (Berra), Zachary
I only cheated once. And even there I think I could get away with a "not guilty" verdict if I had to argue it in court.
from your samples, I have been using the step-by-step version. Which has been working. It seems inefficient, dragging in more variables, despite short lived ones.Example approximating your list-of-lists-of-lists (I think):
B4X:Dim AP As List AP.Initialize Dim FirstList As List FirstList.Initialize AP.Add(FirstList) Dim JournalLedger As List JournalLedger.Initialize AP.Add(JournalLedger) Dim SampleJournalEntries() As String = Array As String( _ "Andy", "11/01/2025", 123.01, _ "Bobby", "19/02/2025", 456.02, _ "Charlie", "08/03/2025", 789.03, _ "Danny", "25/04/2025", 135.04, _ "Ernie", "17/05/2025", 246.05, _ "Freddy", "14/06/2025", 357.06 _ ) For I = 0 To SampleJournalEntries.Length - 1 Step 3 Dim JournalEntry As List JournalEntry.Initialize JournalEntry.Add(SampleJournalEntries(I + 0)) 'name JournalEntry.Add(SampleJournalEntries(I + 1)) 'date JournalEntry.Add(SampleJournalEntries(I + 2)) 'value JournalLedger.Add(JournalEntry) Next Log("*** list of lists of lists ***") Log(AP) Log("*** journal entry lists ***") For I = 0 To 5 Log(I & TAB & AP.Get(1).As(List).Get(I)) Next Log("*** inline ***") For I = 0 To 5 Log( _ I & TAB & _ AP.Get(1).As(List).Get(I).As(List).Get(0) & TAB & _ AP.Get(1).As(List).Get(I).As(List).Get(1) & TAB & _ AP.Get(1).As(List).Get(I).As(List).Get(2) _ ) Next Log("*** step-by-step ***") Dim JournalLedger As List = AP.Get(1) For I = 0 To JournalLedger.Size - 1 Dim JournalEntry As List = JournalLedger.Get(I) Dim JEName As String = JournalEntry.Get(0) Dim JEDate As String = JournalEntry.Get(1) Dim JEValue As String = JournalEntry.Get(2) Log(I & TAB & JEName & TAB & JEDate & TAB & JEValue) Next
Log output:Waiting for debugger to connect... Program started. *** list of lists of lists *** (ArrayList) [[], [[Andy, 11/01/2025, 123.01], [Bobby, 19/02/2025, 456.02], [Charlie, 08/03/2025, 789.03], [Danny, 25/04/2025, 135.04], [Ernie, 17/05/2025, 246.05], [Freddy, 14/06/2025, 357.06]]] *** journal entry lists *** 0 [Andy, 11/01/2025, 123.01] 1 [Bobby, 19/02/2025, 456.02] 2 [Charlie, 08/03/2025, 789.03] 3 [Danny, 25/04/2025, 135.04] 4 [Ernie, 17/05/2025, 246.05] 5 [Freddy, 14/06/2025, 357.06] *** inline *** 0 Andy 11/01/2025 123.01 1 Bobby 19/02/2025 456.02 2 Charlie 08/03/2025 789.03 3 Danny 25/04/2025 135.04 4 Ernie 17/05/2025 246.05 5 Freddy 14/06/2025 357.06 *** step-by-step *** 0 Andy 11/01/2025 123.01 1 Bobby 19/02/2025 456.02 2 Charlie 08/03/2025 789.03 3 Danny 25/04/2025 135.04 4 Ernie 17/05/2025 246.05 5 Freddy 14/06/2025 357.06
LP.Get(1).As(List).Get(0).As(List).Get(2) '0 is the date in the log, 2 is the text from the journal entry
12:20 - Brick layers went for an early lunch and got drunk. The electricians left as it was too dark to work.
that was the best laugh i've had in a long time... cheers Mate!!Lol I thought that only happened here.
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?