Page 1 of 1
Absolute reference to List() defining structure
Posted: Tue Oct 22, 2024 1:43 am
by Psych
Hi guys, just a quick question.
If I have a procedure, like this:
Code: Select all
Procedure IsSameList(list1(),list2())
ProcedureReturn Bool(list1()=list2())
EndProcedure
I will get an error if either list is empty, is there any bulletproof way to get a list reference regardless of whether the list is empty or what position the 'current' element in the list is?
One workaround is to always save the first element in a pointer, but that doesn't help if the first element is removed, or another element is inserted at index 0, for whatever reason.
Apparently, List counts are cached in its own structure, so can we get a reference to that? Maybe that pointer wouldn't bounce around.
Re: Absolute reference to List() defining structure
Posted: Tue Oct 22, 2024 1:53 am
by jacdelad
Hi,
I don't understand what exactly you want to do and also your example function is surely not in your code, because it causes an error on compilation. If you want to use the whole list as parameter (not just the current element, which would also need a different procedure-description), you need to use it like
Code: Select all
Procedure DoSomething(List List1.Type(), List2.Type())
So, what do you want to do?
1. Compare the complete lists with each other, whether all elements are the same?
You have to go through both lists simultanously and compare each item step by step.
2. Compare only the current element?
I don't know your code, so you maybe firstly have to check whether both lists contain valid items (via
ListPosition(MyList())). Then check both elements onto each other.
One more thing: You registered 2008, so this question seems a bit strange to me. Don't want to offend you, just being curious. Working with lists maybe not the first thing to do, but definitely not too advanced. But maybe I just don't understand your question, sorry.
Re: Absolute reference to List() defining structure
Posted: Tue Oct 22, 2024 1:59 am
by idle
I think you need to use it via a structure which mightn't be ideal
Code: Select all
Structure mlist
List l.i()
EndStructure
Procedure IsSameList(*list1.mlist,*list2.mlist)
If *list1 And *list2
ProcedureReturn Bool(*list1=*list2)
EndIf
EndProcedure
Global l1.mlist
Global l2.mlist
Debug IsSameList(@l1,@l1)
AddElement(l1\l())
l1\l() = 123
Debug IsSameList(@l1,@l2)
Re: Absolute reference to List() defining structure
Posted: Tue Oct 22, 2024 2:26 am
by Psych
idle wrote: Tue Oct 22, 2024 1:59 am
I think you need to use it via a structure which mightn't be ideal
Code: Select all
Structure mlist
List l.i()
EndStructure
Genius, I hadn't thought about wrapping the lists. This makes a lot more sense, at least in the short term.
Its a shame we don't have ListID(list()) to give us that unique address of the lists defining structure though.
Might cause a few more headaches with intialising and destroying as I am assuming the list inside the structure wont ever go out of scope (maybe it will, but let's be safe). Either way it's a start, thanks a lot.
Re: Absolute reference to List() defining structure
Posted: Tue Oct 22, 2024 3:07 am
by idle
Psych wrote: Tue Oct 22, 2024 2:26 am
idle wrote: Tue Oct 22, 2024 1:59 am
I think you need to use it via a structure which mightn't be ideal
Code: Select all
Structure mlist
List l.i()
EndStructure
Genius, I hadn't thought about wrapping the lists. This makes a lot more sense, at least in the short term.
Its a shame we don't have ListID(list()) to give us that unique address of the lists defining structure though.
Might cause a few more headaches with intialising and destroying as I am assuming the list inside the structure wont ever go out of scope (maybe it will, but let's be safe). Either way it's a start, thanks a lot.
also you can do this if you needed to check if two lists are equal
Code: Select all
Structure mlist
List l.i()
EndStructure
Procedure IsSameList(*list1.mlist,*list2.mlist)
If *list1 = *list2
ProcedureReturn -1
Else
ProcedureReturn CompareStructure(*list1,*list2,mlist)
EndIf
EndProcedure
Global l1.mlist
Global l2.mlist
If IsSameList(@l1,@l1) = -1
Debug "is the same list"
EndIf
AddElement(l1\l())
l1\l() = 123
If IsSameList(@l1,@l2) = 0
Debug "l1 <> l2"
EndIf
AddElement(l2\l())
l2\l()=123
If IsSameList(@l1,@l2) = 1
Debug "l1 = l2"
EndIf
Re: Absolute reference to List() defining structure
Posted: Tue Oct 22, 2024 4:15 am
by AZJIO
I don't remember why this works. This is not documented.
Code: Select all
Procedure IsSameList(List list1(), List list2())
Protected c1, c2
c1 = ListSize(list1())
c2 = ListSize(list1())
If c1 And c1 = c2
ProcedureReturn Bool(list1()=list2())
ElseIf c1 = 0 And c1 = c2
ProcedureReturn 1
EndIf
ProcedureReturn 0
EndProcedure
Define NewList list1()
Define NewList list2()
Debug IsSameList(list1(),list2())
For i = 0 To 20
AddElement(list1())
list1() = i
AddElement(list1())
list1() = i
Next
AddElement(list1())
list1() = 4
AddElement(list1())
list1() = 4
AddElement(list2())
list2() = 4
AddElement(list2())
list2() = 4 ; change the number to prove that list comparison works
Debug IsSameList(list1(),list2())
This also works with a list of strings.
Code: Select all
Procedure IsSameList(List list1.s(), List list2.s())
Protected c1, c2
c1 = ListSize(list1())
c2 = ListSize(list1())
If c1 And c1 = c2
ProcedureReturn Bool(list1()=list2())
ElseIf c1 = 0 And c1 = c2
ProcedureReturn 1
EndIf
ProcedureReturn 0
EndProcedure
Define NewList list1.s()
Define NewList list2.s()
Debug IsSameList(list1(),list2())
For i = 0 To 20
AddElement(list1())
list1() = Str(i)
AddElement(list1())
list1() = Str(i)
Next
AddElement(list1())
list1() = "fuf"
AddElement(list1())
list1() = "fuf"
AddElement(list2())
list2() = "fuf"
AddElement(list2())
list2() = "fuf" ; change the letter to prove that list comparison works
Debug IsSameList(list1(),list2())
Re: Absolute reference to List() defining structure
Posted: Tue Oct 22, 2024 6:33 am
by DarkDragon
AZJIO wrote: Tue Oct 22, 2024 4:15 am
I don't remember why this works. This is not documented.
You're comparing the selected elements of the lists if their size is equal. You don't compare the list itself. It's also happening in OP's original post.
Re: Absolute reference to List() defining structure
Posted: Tue Oct 22, 2024 6:53 am
by AZJIO
I didn't know that I could be deceived. My examples don't make sense. I just forgot that the list represents the current element.
But in fact, in special functions (ListSize, CompareList), the list is an object, not an element. That's why I fell for the scam with the Bool function.
Re: Absolute reference to List() defining structure
Posted: Tue Oct 22, 2024 8:47 am
by idle
It needs to be done through a structure with a list for now.
If you do it by address of a list it will only work from global scope.
So for a list list1() you can get it's address as @list1 but you can't get that from within a Procedure with a list parameter as it will just get the address of the parameter off the stack.
Re: Absolute reference to List() defining structure
Posted: Tue Oct 22, 2024 2:41 pm
by Mesa
I don't know if it helps, but PB has a new procedure to compare 2 lists.
Code: Select all
Procedure IsSameList(List list1.s(),List list2.s())
ProcedureReturn CompareList(list1(),list2())
EndProcedure
NewList A$()
AddElement(A$()) : A$() = "Jean"
AddElement(A$()) : A$() = "Charles"
AddElement(A$()) : A$() = "Didier"
NewList B$()
AddElement(B$()) : B$() = "JEAN" ; <==
AddElement(B$()) : B$() = "Charles"
AddElement(B$()) : B$() = "Didier"
Debug CompareList(A$(), B$()) ; 0
Debug CompareList(A$(), B$(), #PB_String_NoCase) ; 1=equal
Debug IsSameList(A$(), B$()); 0
M.