Grabbing Objects from a Table IF

Let me cut right to the chase. How exactly would I go about grabbing a random item with in a table IF it’s boolean value is true. Essentially, I want to randomly select something from the table, but what’s selected must be set to false rather than true if that makes sense.

I’ve considered, math.random for getting a random thing with in the table, but how exactly to get something with a value of false specifically and avoiding any thing that is set as true.

image

Any examples or ideas? Below is the layout of my table too. If you need further clarification I’m willing to explain.

image

2 Likes

in my Math module. there is a function called filterT

filterT: Gets a table and a function, returns a new table with the elements that evaluated the function f(value, key) to true

you can do

local t = Math.filterT(UsedCharacters, function(value, key)
    return value == false
end)

after that you can pick a random item from the new table easily

local randomCharacter = t[math.random(1, #t)]

I get attempt to call a nil value, and if I understand you correctly, I laid it out just right.

1 Like

Uh sorry, gotta fix something real quick. otherwise the concept is the same
you just have to make a new table with the values that are false and then select a random item from them.

I’ll fix my function asap, I got a typo

So one solution that I thought of just now has 2 parts: 1st part is do as you are doing now except I question why you say

table[math.random(1, #UsedCharacters)]

instead of

UsedCharacters[math.random(1, #UsedCharacters)]

After you get the random value, you will use a while loop to check if the value is true or false depending on what you need it to be. If it is not what you need it to be, then go up one value and check that one. If that one is not what you need, then go down one from the original value. If that is not what you need then go up 2 from the original value. If that is not what you need then go down 2 from the original value. Until you find a value that can be used, you just keep going up 1 then down 1 from the randomly selected value and then up 2 down 2 then up 3 down 3 checking all the closest values to the randomly picked value.

What exactly is the difference between the two anyways, and how would I go about using a while loop in a PlayerAdded triggered event.

Here is a working snippet I made. Just make sure to have the latest version of my library

local Math = require(script.ModuleScript)

local t = {
	a = false,
	b = true,
	c = false
}

local filteredTable = Math.filterT(t, function(value, key)
	return value == false
end)

local keys = Math.keysT(t)
local randomKey = keys[math.random(1, #keys)]
print(randomKey)

image

that’s gonna be a big turn off for performance. and it will crash the game if no value is equal to false

I believe this is working, however, how do I change the boolean value with in the original table from false for the chosen random object.

1 Like

Can you clarify please? because am not sure what you’re trying to do, and there is probably a better way to do what you think but let me know

I guess you could say, is there a special way I should be changing the value of the chosen object to true from false from the randomizer module here

does that clarify?

you mean something like local rig = Rigs[randomKey] ??

So we’ve got it so it chooses a random object from the table if it’s boolean value is false, but I need to take the object thats chosen with in the table and make it’s value true, so it’s avoided in the future.

So you want to set the value to false if the index is chosen? If so you will need to update the index through the original table since Math.filter returns a clone of the original table but is just filtered.

UsedCharacters[randomKey] = true
Edit the original table with the key, not the new filtered table

To respond to @IlyasTawawe , I didn’t even write the code but no it would not crash the script or thread. As for performance, it is one of the best without creating new arrays or tables and without compromising the randomness. If you create a new table, you can make it significantly faster IF you are doing it on a large quantity of data.

To respond to Juggersnaut, I don’t know what his module does. To use a while loop, it would look something like this:

local max = #UsedCharacters
local rand = math.random(1, max)
local numUp = rand
local numDown = rand
local selected = nil
while true do
  if UsedCharacters[numUp]==true then
    selected=numUp
    break
  elseif UsedCharacters[numDown]==true then
    selected=numDown
    break
  end
  numUp = numUp+1
  numDown = numDown-1
  if numDown < 0 then
    numDown=0
    if numUp==max then break end
  end
  if numUp > max then
    numUp = max
    if numDown==0 then break end
  end
end
if not selected then
  print("Found none true")
else
  print("Found "..tostring(selected).." to be true")
end

[Edited to make the while loop have an end]

1 Like

That wouldn’t really work since anything after a while loop won’t run. Unless you are using a coroutine.

and I have plenty that needs to run afterwards,

It would work, but you’re doing guess work. your function’s speed can go from the best to the absolute worst depending on the situation. on the other hand doing it the table way will guarantee the consistency and the speed in any case with a penalty of temporary small memory footprint!

Does your module change everything with in my table that’s false to true or just a random objects value?

1 Like