Round number to closest key in dictionary

I’m trying to round a magnitude to the closest key in a dictionary, for example if magnitude is between 0 to 14 (or 15) round it to 15, numbers between 16 and 25 round to 25 and so on.
Solutions like Finding the Closest Number to a Given One in an Array don’t exactly work.
Here is my dictionary.

return {
	Magnitudes = {
		[15] = {
			["StunTime"] = 3,
			["Damage"] = 150,
			["ConcussionEnabled"] = true,
			["Ragdoll"] = true,
			["RagdollTime"] = 2.5
		},
		[25] = {
			["StunTime"] = 1.5,
			["Damage"] = 65,
			["ConcussionEnabled"] = true,
			["Ragdoll"] = true,
			["RagdollTime"] = 1.5
		},
		[35] = {
			["StunTime"] = 0.7,
			["Damage"] = 45,
			["ConcussionEnabled"] = true,
			["Ragdoll"] = true,
			["RagdollTime"] = 0.5
		},
	},
}
2 Likes

let me know if this works:

local Array = {
	Magnitudes = {
		[15] = {
			["StunTime"] = 3,
			["Damage"] = 150,
			["ConcussionEnabled"] = true,
			["Ragdoll"] = true,
			["RagdollTime"] = 2.5
		},
		[25] = {
			["StunTime"] = 1.5,
			["Damage"] = 65,
			["ConcussionEnabled"] = true,
			["Ragdoll"] = true,
			["RagdollTime"] = 1.5
		},
		[35] = {
			["StunTime"] = 0.7,
			["Damage"] = 45,
			["ConcussionEnabled"] = true,
			["Ragdoll"] = true,
			["RagdollTime"] = 0.5
		},
	},
}

local function FindInterval(Magnitude)
	local Lowest = math.huge
	local BestInterval = nil
	for Key, Value in pairs(Array.Magnitudes) do
		local Distance = math.abs(Magnitude - Key)
		if Magnitude <= Key and Distance <= Lowest then
			Lowest = Distance
			BestInterval = Key
		end
	end
	return BestInterval
end

local BestInterval = FindInterval(16)
print(BestInterval)
local function closestIndex<T>(t: {[number]: T}, i: number): T
	local closest: number, element: T = math.huge, nil
	for k, v in t do
		local delta: number = math.abs(k - i)
		if delta < closest then
			closest = delta
			element = v
		end
	end
	return element
end

local t = {
	[15] = 15,
	[20] = 20,
	[35] = 35,
}
print(closestIndex(t, 0)) --> 15
print(closestIndex(t, 10)) --> 15
print(closestIndex(t, 19)) --> 20
print(closestIndex(t, 1000)) --> 35
local Magnitude = FindInterval(RisytalModules:ReturnDistance(Character, Rocket), Config)
print(Magnitude)
Character.Humanoid:TakeDamage(Magnitude.Damage)

It find the key but it doesn’t return its arrays and keys.

now it should return the key’s array

local Array = {
	Magnitudes = {
		[15] = {
			["StunTime"] = 3,
			["Damage"] = 150,
			["ConcussionEnabled"] = true,
			["Ragdoll"] = true,
			["RagdollTime"] = 2.5
		},
		[25] = {
			["StunTime"] = 1.5,
			["Damage"] = 65,
			["ConcussionEnabled"] = true,
			["Ragdoll"] = true,
			["RagdollTime"] = 1.5
		},
		[35] = {
			["StunTime"] = 0.7,
			["Damage"] = 45,
			["ConcussionEnabled"] = true,
			["Ragdoll"] = true,
			["RagdollTime"] = 0.5
		},
	},
}

local function FindInterval(Magnitude)
	local Lowest = math.huge
	local BestInterval = nil
	for Key, Value in pairs(Array.Magnitudes) do
		local Distance = math.abs(Magnitude - Key)
		if Magnitude <= Key and Distance <= Lowest then
			Lowest = Distance
			BestInterval = Key
		end
	end
	return Array.Magnitudes[BestInterval]
end

local BestInterval = FindInterval(16)
print(BestInterval["StunTime"])

you might also want to clamp the value, in case it goes beyond the maximum magnitude limit:

local Array = {
	Magnitudes = {
		[15] = {
			["StunTime"] = 3,
			["Damage"] = 150,
			["ConcussionEnabled"] = true,
			["Ragdoll"] = true,
			["RagdollTime"] = 2.5
		},
		[25] = {
			["StunTime"] = 1.5,
			["Damage"] = 65,
			["ConcussionEnabled"] = true,
			["Ragdoll"] = true,
			["RagdollTime"] = 1.5
		},
		[35] = {
			["StunTime"] = 0.7,
			["Damage"] = 45,
			["ConcussionEnabled"] = true,
			["Ragdoll"] = true,
			["RagdollTime"] = 0.5
		},
	},
}

local function FindInterval(Magnitude)
	local Magnitude = math.clamp(Magnitude,0,35)
	local Lowest = math.huge
	local BestInterval = nil
	for Key, Value in pairs(Array.Magnitudes) do
		local Distance = math.abs(Magnitude - Key)
		if Magnitude <= Key and Distance <= Lowest then
			Lowest = Distance
			BestInterval = Key
		end
	end
	return Array.Magnitudes[BestInterval]
end

local BestInterval = FindInterval(10000)
print(BestInterval["Damage"])

Yeah I figured I’ll just do this.

if RisytalModules:ReturnDistance(Character, Rocket) <= Config.MaximumDistance then
	local Magnitude = FindInterval(RisytalModules:ReturnDistance(v.Character, Rocket), Config)
	print(Magnitude)
	Character.Humanoid:TakeDamage(Magnitude.Damage)
end

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.