Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How to compare two tables for the same values?

Asked by 5 years ago
Edited 5 years ago

I've been programming for a long time now, and one question that has plagued me is this. I've been able to find workarounds, but no longer.

I'm creating a terrain generator, and the idea behind it is this: Put nearby terrain parts into a table Put possible terrain locations into a table

If a nearby terrain part has the same location as a possible terrain location, remove it from the table.

Create terrain

Seems simple, right? Ideally one would assume this would work:

for _, nearGridTable in pairs(nearbyGrid) do
    for index, nearPositions in pairs(possibilities) do
        if nearGridTable == nearPositions then
        print("same")
        table.remove(possibilities, index)
        print("removed")
        end
    end
end

The issue I run into however is, my print's never run. That has lead me to believe that the nearGridTable is never equaling nearPositions.

On further analysis, there are duplicate values in both table, this for loop is just not getting them properly.

I've had a few ideas on how one might go about fixing it: Idea 1: Check the values before I put it into the table This wouldn't work, as it would be inefficient for my use case. Idea 2: use table.sort()

However, that doesn't sort my tables properly (I'm storing vector3 values). I could go about making my own sort function. I've never done this, and so essentially I come before everyone asking, what would you do to compare two tables?

Full code so you understand the context of what I'm working on:

-- Made by Conmmander --
-- terrainCore --
-- Last Edit: 9-2-2018, 2:55 PM --

-- Inititalization --

print("Intialization | "..script.Name)

-- Game Services --

local workspaceService = game:GetService("Workspace")
local playerService = game:GetService("Players")
local lightingService = game:GetService("Lighting")
local replicatedStorage = game:GetService("ReplicatedStorage")
local serverStorage = game:GetService("ServerStorage")
local starterGui = game:GetService("StarterGui")
local starterPack = game:GetService("StarterPack")
local chatService = game:GetService("Chat")

-- Game Folders --

local terrainStorage = serverStorage:FindFirstChild("terrainStorage")

local baseTerrain = terrainStorage:FindFirstChild("baseTerrain")
local buildingTerrain = terrainStorage:FindFirstChild("buildingTerrain")

-- Configuration --

local ignoreCordinates = {}
local baseLimit = 100
local yCord = .5
local mingenerationRange = 12
local maxgenerationRange = 15

-- Variables --

local bases = 0
local initialSetup = false

-- Functions --

function countTerrain()
    bases = 0
    for _, defaultPart in pairs(workspaceService:GetChildren()) do
        if defaultPart.Name == "defaultGrid" then
            bases = bases + 1
        end
    end
end

function generateTerrain(player)
    local nearbyGrid = {}
    local possibilities = {}
    if initialSetup == false then
        local position = CFrame.new(math.random(math.randomseed(1)), yCord, math.random(math.randomseed(1)))
        local clonedBase = baseTerrain.defaultGrid:Clone()
        clonedBase:SetPrimaryPartCFrame(position)
        clonedBase.Parent = workspaceService
        initialSetup = true
    end
    local debounce = false
    countTerrain()
    if bases < baseLimit then
    local Torso = player.Character.HumanoidRootPart
    local base = player.Character.RightFoot
    base.Touched:Connect(function(hitPart)
        wait(.1)
        if debounce == false then
        debounce = true
        if hitPart.Parent.Name == "defaultGrid" then
            if (hitPart.Parent.centerPart.Position-Torso.Position).Magnitude >= mingenerationRange and (hitPart.Parent.centerPart.Position-Torso.Position).Magnitude < maxgenerationRange then
                wait(.1)
                local debounce2 = false
                if debounce2 == false then
                debounce2 = true
                table.insert(possibilities, hitPart.Parent.centerPart.Position - Vector3.new(0, 0, 30))
                table.insert(possibilities, hitPart.Parent.centerPart.Position + Vector3.new(0, 0, 30))
                table.insert(possibilities, hitPart.Parent.centerPart.Position - Vector3.new(30, 0, 0))
                table.insert(possibilities, hitPart.Parent.centerPart.Position + Vector3.new(30, 0, 0))
                print("Insert")
                for _, leftPart in pairs(hitPart.Parent.left:GetTouchingParts()) do
                    print("Called")
                    if leftPart.Parent.Name == "defaultGrid" then
                        table.insert(nearbyGrid, leftPart.Parent.centerPart.Position)
                        print("Insertleft")
                    end
                end
                for _, rightPart in pairs(hitPart.Parent.right:GetTouchingParts()) do
                    print("Called")
                    if rightPart.Parent.Name == "defaultGrid" then
                        table.insert(nearbyGrid, rightPart.Parent.centerPart.Position)
                        print("Insertright")
                    end
                end
                for _, nearGridTable in pairs(nearbyGrid) do
                    for index, nearPositions in pairs(possibilities) do
                        if nearGridTable == nearPositions then
                            print("same")
                            table.remove(possibilities, index)
                            print("removed")
                        end
                    end
                end
                for _, position in pairs(possibilities) do
                    local clonedBase = baseTerrain.defaultGrid:Clone()
                    clonedBase:SetPrimaryPartCFrame(CFrame.new(position))
                    clonedBase.Parent = workspaceService
                end
                end
                debounce2 = false
            end
        end
        end
        wait(.2)
    debounce = false
    end)

    end
end

-- Code --

playerService.PlayerAdded:Connect(function(addedPlayer)
    addedPlayer.CharacterAdded:Connect(function(addedCharacter)
        generateTerrain(addedPlayer)
    end)
end)

-- Loop --

while true do
    wait(5)
    for _, players in pairs(playerService:GetPlayers()) do
        generateTerrain(players)
    end
end

EDIT:

Some nice person I spoke with yesterday sent me this as a method of sorting tables, but how would I use it? (I'm not very familiar with sorting tables).

local function unordered_tostring_equals(array_1, array_2)
    -- making count_diffs[unknown] return 0 instead of nil
    -- I usually I have have a function for this: count_diffs = DefaultedTable(0)
    local count_diffs = setmetatable({}, {__index = function()
            return 0
    end})

    -- adds 1's counts
    for _, v in ipairs(array_2) do
        local str = tostring(v)
        count_diffs[str] = count_diffs[str] + 1
    end

    -- subtracts 2's counts
    for _, v in ipairs(array_1) do
        local str = tostring(v)
        count_diffs[str] = count_diffs[str] - 1
    end

    -- if the same tostrings has a different count, it's a different table
    for _, count in pairs(count_diffs) do
        if count ~= 0 then
            return false
        end
    end

    return true
end
0
Yes I did, there are identical Vector3 values. Conmmander 479 — 5y
0
nvm i re-read your post and found out you said that already aazkao 787 — 5y

Answer this question