How Table.find actually works, open source function

function table.FIND(Table,value,index)
  if type(Table)~='table' then
    return error("bad argument #1 to 'FIND' (table expected, got "..type(Table).." )")
  elseif value==nil then
    return error("bad argument #2 to 'FIND' (String or Boolean or Number expected, got "..type(value).." )")
  elseif index and index > #Table then
    return nil
  end
  for i=index or 1,#Table,1 do
    if Table[i]==value then
    return i
    elseif i==#Table and Table[i]~=value then
    return nil
      end
   end
end
-- End Of Function
local Our_Table={1,2,3,4,5,6,'plr',true,false}
-- comparison
print(table.find(Our_Table,true,4)) -- Roblox's function
print(table.FIND(Our_Table,true,4))-- our function
3 Likes
--!strict

local table = setmetatable({}, { __index = table })
function table.FIND(array, needle, init)
	if type(array) ~= "table" then
		return error("invalid argument #1 to 'FIND' (table expected, got " .. type(array) .. ")")
	elseif needle == nil then
		return nil
	end
	local inext = ipairs(array)
	local i, value = if init then init - 1 else 0
	while true do
		i, value = inext(array, i)
		if value == nil then
			return nil
		end
		if value == needle then
			return i
		end
	end
end

local function test(find)
  local t = table.create(5)
  assert(#t == 0) -- filled with nil!
  t[5] = 5
  assert(#t == 5) -- magic

  local t2 = table.create(5, "nice")
  assert(table.concat(t2,"!") == "nice!nice!nice!nice!nice")

  assert(find(t2, "nice") == 1)
  assert(find(t2, "nice", 5) == 5)
  assert(find(t2, "nice", 6) == nil)

  assert(find({false, true}, true) == 2)

  -- make sure table.find checks the hash portion as well
  assert(find({[(2)] = true}, true, 2) == 2)
end

test(table.find)
test(table.FIND)
1 Like

Id like to keep it simple soooo :slight_smile: :slight_smile:

This is how table.find is actually implemented in the VM.

static int tfind(lua_State* L)
{
    luaL_checktype(L, 1, LUA_TTABLE);
    luaL_checkany(L, 2);
    int init = luaL_optinteger(L, 3, 1);
    if (init < 1)
        luaL_argerror(L, 3, "index out of range");

    Table* t = hvalue(L->base);
    StkId v = L->base + 1;

    for (int i = init;; ++i)
    {
        const TValue* e = luaH_getnum(t, i);
        if (ttisnil(e))
            break;

        if (equalobj(L, v, e))
        {
            lua_pushinteger(L, i);
            return 1;
        }
    }

    lua_pushnil(L);
    return 1;
}

The closest implementation in Luau would be a linear search, but the native function is always faster because it can interact directly with the VM without safety checks.

local function Find<Value>(Array: {Value}, Needle: Value, Initial: number?): number?
	for Index = Initial or 1, #Array do
		if Array[Index] == Needle then
			return Index
		end
	end
	
	return nil
end
8 Likes

What’d you expect, it’s AlreadyPro

what did i do to deserve this :sob:

I feel you bro i feel you :sob: :sob: :sob:

1 Like