Lets say I have multiple objects which are represented by 3 numbers (a, b and c) but I need to combine those three numbers into 1 number which would be unique for each object. For example:
Object 1
a = 1
b = 3
c = 2
Object 2
a = 3
b = 1
c = 2
I can’t just add or multiply a, b and c together as both objects would end up having the same number. Any ideas?
That seems pretty complex, what I’m trying to achieve should be pretty simple, @AyeeAndrxw gave a good idea, maybe you know how I’d combine 3 different numbers into 1 longer one?
If they are three variables, you could just do what @Wunder_Wulfe said.
Ultimately, it depends on how many UIDs you need, if you are going to need more than 75~+, I would definitely recommend using a form of hashing to ensure that it is unique
What you’re really talking about is how to hash your elements. I would recommend looking up videos on what hashing is and how it works. But, for the sake of example, here is a hashing algorithm for this specific a,b,c data type you showed (it assumes all three values lie in the range [0, 9]):
function hash(element)
return element.a * 100 + element.b * 10 + element.c
end
Basically what I’m trying to do is instead of having a 3D array like this Array[x][y][z], having a 1D array like this Array[xyz] which would be more performant and more hassle free. I think your solution is perfect for this, thanks.
For the record, Lua already uses hashing for all table keys. In fact, you can even use a table reference as your key! That is, you can already just do this:
local cacheThing = {}
local element = {
a = 1,
b = 3,
c = 2
}
cacheThing[element] = true
print(cacheThing[element])
Your output will be something like table: 0x7539439
In the 3D array case u can simply use dimensional indexxing (array index being x + y*xdim + z*xdim*ydim) given the values are in range of the dimensions or u could also try using “x,y,z” as the index or something of the sort
Are you sure you need the performance gains? I’ve never had issues with multidimensional Tables and the performance difference is minimal at best for a 3D table vs. a 1D Table.
Serializing the data is a different issue, but there isn’t enough information here to give you accurate advice. Can you show us some code, or give some more details as to what you’re doing with this?
For serialization, if you’re accessing the data relatively rarely, I’d use concatenation-with-separators:
Array[x .. ":" .. y .. ":" .. z]
However, since concatenation is much slower than multiplication regardless of how you do it, I’d use Wunder_Wulfe’s suggestion of dimensional indexing if the array was getting accessed more frequently. This requires knowing the size of the “inner” dimensions:
Array[x + y*xdim + z*ydim*xdim]
-- a micro-optimization here is to memoize ydim*xdim if they don't change
But only if I absolutely had to use this 1D array. Otherwise I’d just stick to the 3D array and make helper functions to modify it as needed.
-- cantor pairing function for 2 natural numbers
local function cantor2(x, y)
return (x*(x + 3) + y*(y + 1))/2 + x*y
end
-- cantor pairing function for 3 natural numbers
local function cantor3(x, y, z)
return cantor2(cantor2(x, y), z)
end