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.