Page 1 of 1
Compare Structs and Arrays for equality
Posted: Sun Jan 19, 2025 1:36 pm
by JeJe
Simple way to compare any two Structs for equality, without testing each member against one another, using an EnumerableMap.
Code: Select all
sub testCompareStructs
dim f1 as new com.sun.star.awt.FontDescriptor
dim f2 as new com.sun.star.awt.FontDescriptor
msgbox compareStructs(f1,f2)
f1.weight = 300
msgbox compareStructs(f1,f2)
end sub
function compareStructs(struct1,struct2)
dim EnMap
EnMap = com.sun.star.container.EnumerableMap.create("string", "any")
EnMap.put("0", struct1)
compareStructs = EnMap.containsValue(struct2)
end function
Re: Compare Structs and Arrays for equality
Posted: Sun Jan 19, 2025 2:13 pm
by JeJe
We can also compare arrays using the same function, so I've amended the thread title
Code: Select all
sub testCompareArrays
dim s1(10000)
dim s2(10000)
msgbox compareStructsOrArrays(s1,s2)
s1(500) = thiscomponent
msgbox compareStructsOrArrays(s1,s2)
s2(500) = thiscomponent
msgbox compareStructsOrArrays(s1,s2)
end sub
function compareStructsOrArrays(struct1,struct2)
dim EnMap
EnMap = com.sun.star.container.EnumerableMap.create("string", "any")
EnMap.put("0", struct1)
compareStructsOrArrays = EnMap.containsValue(struct2)
end function
Re: Compare Structs and Arrays for equality
Posted: Sun Jan 19, 2025 2:21 pm
by JeJe
We can't compare two user defined types but we could use, as a substitute, an array with named constants for the array indexes.
Re: Compare Structs and Arrays for equality
Posted: Sun Jan 19, 2025 4:13 pm
by karolus
JeJe wrote: ↑Sun Jan 19, 2025 1:36 pm
Simple way to compare any two Structs for equality,…
ROFL
Code: Select all
from com.sun.star.awt import FontDescriptor as fs
def compare( one, other):
return one == other
def main():
desc1 = fs()
desc2 = fs()
print(compare(desc1,desc2)) #True
desc2.Weight = 300.0
print(compare(desc1, desc2)) #False
Re: Compare Structs and Arrays for equality
Posted: Sun Jan 19, 2025 10:59 pm
by JeJe
Thanks karolus,
Its simple compared to the alternative in Basic of testing each member and possibly writing a separate function for each struct.
Provided you have a generic function, like mine, which is exactly the same to call as an inbuilt one, then the difference, (needing the function in a loaded library) is slight to negligible.
Re: Compare Structs and Arrays for equality
Posted: Tue Jan 21, 2025 2:54 am
by JeJe
It might be possible to compare user defined types [edit: generically, one function for all] using the CoreReflection service, but I couldn't work it out.
Another alternative, instead of an array as a substitute for a user type, is to build a substitute by joining Pair structs together.
I'm not sure there's any advantage over an array though:
Code: Select all
sub TestStructEnum
struct1 = CreateStructEnum(array(0,1,thiscomponent,3,4,5,6,7,8))
struct2 = CreateStructEnum(array(0,1,thiscomponent,3,4,5,6,7,8))
struct3 = CreateStructEnum(array(0,1,thiscomponent,3,4,5,60,7,8))
msgbox compareStructs(struct1,struct2)
msgbox compareStructs(struct1,struct3)
const seconditemname = 2 'set const for accessing index by name
mri GetStructEnumValue(struct1,seconditemname)
end sub
Function CreateStructEnum(arr)
dim ub,i
ub = ubound(arr)
dim pairs(ub)
for i = 0 to ub
pairs(i) = new "com.sun.star.beans.Pair<any,any>" 'first any can be another data type
pairs(i).first = arr(i)
next
for i = ub -1 to 0 step -1
pairs(i).second = pairs(i+1)
next
CreateStructEnum = pairs(0)
end function
function GetStructEnumValue(struct,v) as any
on local error goto outofrange
dim n,i
if v = 0 then
GetStructEnumValue = struct.first
else
n = struct
for i = 0 to v-1
n = n.second
next
GetStructEnumValue =n.first
end if
outofrange:
end function
function compareStructs(struct1,struct2)
dim EnMap
EnMap = com.sun.star.container.EnumerableMap.create("string", "any")
EnMap.put("0", struct1)
compareStructs = EnMap.containsValue(struct2)
end function
Re: Compare Structs and Arrays for equality
Posted: Wed Jan 22, 2025 3:46 pm
by JeJe
Continuing the theme of alternatives to user types, we can also of course also borrow an existing struct if we can find one which has the fields we need.
Code: Select all
option VBAsupport 1
enum MyEnum
firstvalue = 0
secondvalue = 1
thirdvalue = 2
end enum
sub testMystruct
dim mystruct1
mystruct1 = new "com.sun.star.chart.TimeIncrement" 'BORROW A TimeIncrement struct which has 3 Any variables
setstructvalue mystruct1, myEnum.secondvalue, thiscomponent 'our own enum value or constant value for field index
mri getstructvalue(mystruct1,myEnum.secondvalue)
End Sub
function getStructValue(struct, index as long) as any 'Generic function for any struct
dim CR,ACR
CR =createunoservice("com.sun.star.reflection.CoreReflection")
ACR = CR.getType(struct)
getStructValue = ACR.fields(index).get(struct)
end function
function setStructValue(byref struct, index as long,value) 'Generic function for any struct
Dim CR,ACR
CR =createunoservice("com.sun.star.reflection.CoreReflection")
ACR = CR.getType(struct)
ACR.fields(index).set(struct,value)
end function
Re: Compare Structs and Arrays for equality
Posted: Fri Jan 31, 2025 10:59 am
by mikekaganski
JeJe wrote: ↑Tue Jan 21, 2025 2:54 am
It might be possible to compare user defined types [edit: generically, one function for all] using the CoreReflection service
Unfortunately, it isn't. The CoreReflection service is for introspection into UNO; and the user-defined type is a Basic type, with no UNO representation.
Re: Compare Structs and Arrays for equality
Posted: Fri Jan 31, 2025 11:18 am
by JeJe
mikekaganski wrote: ↑Fri Jan 31, 2025 10:59 am
Unfortunately, it isn't. The CoreReflection service is for introspection into UNO; and the user-defined type is a Basic type, with no UNO representation.
Thanks... all I got with MRI was one field of type ANY and unable to inspect further.
Still, I see little difference between using a variant array with named constants for the indexes and a user type... except you can traverse the items, resize the array, use sort algorithms, and compare them as above - all advantages.