Best way to remove a certain number of items from a table?

Hello Devfourm,

I am need to figure out how I could remove a [certain] number of items from a table and ONLY that amount?

I have this Shiny system for my game revolving around pets and players need 10 pets to make that pet shiny. What’s the best way to remove 10 of that exact same pet from their table whilst retaining the others if they have more of that same pet? The indexes are obviously going to be random (saying this by the index of whatever pet is the same as the one they’re trying to make shiny)

So really, what’s the best way to remove an exact amount of specified items from a table?

Your pet system shouldn’t have multiple tables for the same pet?

what it should look like is being inside 1 table like this:

{
Name = "Cat",
Amount = 10,
--// Other descriptive properties
}

And you can remove 9 from that single pet and make it “shiny”.

The method it appears you’re using is very inefficient.

Uh? What? Every pet has their own table of pet data, I can’t have an ‘amount’ value. Every pet has their own xp, level, etc, so an ‘amount’ value with 1 table cannot be made. It’s not inefficient.

If its a full inventory, and the pets dont stack, you can keep doing a for loop and removing the pets:

local pets = {}
for i = 1,amounttoremove do
   table.remove(pets,table.find(pets,petdata))
end
1 Like

You could create a function and call it
local function removePetFromTable(table, petName, amountToRemove)

Then you could add the functionality like so:

local function removePetFromTable(petTable, petToRemove, amountToRemove)
    for i = 1, amountToRemove, 1 do
        if petTable[i].Name == petToRemove then
            table.remove(petTable, i)
        end
    end
end

Then you could call it like this.

local pets = {...}
removePetFromTable(pets, "Green Cat", 10)
1 Like

It wouldn’t change the table though, maybe return the new edited table and set it as pets, i’m pretty sure it wouldn’t replicate from removePetsFromtable function to the actual script.

For some reason it’s not removing 10 pets for me, it’s like removing a random amount.

Yeah it’s because he/she is only checking 10 of the first pets in the table, when they should be checking all of them and then breaking the loop after 10 pets removed. I’m sure you can add that yourself.

Sorry I wrote that too quickly lol.

local function removePetFromTable(petTable, petToRemove, amountToRemove)
    local amountRemoved = 0

    while (amountRemoved < amountToRemove) do
      local petFound = false

      for i = 1, #petTable, 1 do
          if petTable[i] and petTable[i].Name == petToRemove then
              table.remove(petTable, i)
              amountRemoved = amountRemoved + 1
              petFound = true
              break
          end
      end
      if not petFound then
          break
      end
    end
end

That should work…

1 Like

Are you sure?

local function removePetFromTable(petTable, petToRemove, amountToRemove)
    local amountRemoved = 0
    local petNotExistant = false
    while (amountRemoved < amountToRemove) and not petNotExistant do
      for i = 1, #petTable, 1 do
          if petTable[i] and petTable[i].Name == petToRemove then
              print(petTable[i].Name)
              table.remove(petTable, i)
              amountRemoved = amountRemoved + 1
              break
          end
      end
      petNotExistant = true
    end
end

That should work for you.

1 Like

You got the wrong idea it seems — I was trying to show him / her that your code directly modifies the petTable therefore doesn’t require any returns.

Yeah I was going to say something to him lol but you clarified that for me. Thanks. It does pass by reference.

Hey I just wanted to give this to you. Because I fixed all the edge cases.

local function removePetFromTable(petTable, petToRemove, amountToRemove)
    local amountRemoved = 0

    while (amountRemoved < amountToRemove) do
      local petFound = false

      for i = 1, #petTable, 1 do
          if petTable[i] and petTable[i].Name == petToRemove then
              table.remove(petTable, i)
              amountRemoved = amountRemoved + 1
              petFound = true
              break
          end
      end
      if not petFound then
          break
      end
    end
end

I hope this helped you out.