How to take one of each in a table?

22 replies
Goto Page
1 2
Promaster
User
Offline
For example i have a table
testtable1 = {1,1,1,1,2,2,2,2,3,3,3,3,5,5,5}
I want to create another table who one element of each in testtable1 --->
testtable2 = {1,2,3,5}

I think there is a kind of table.something? Like table.sort?

Ty for helping
Patch 13.1! Updated. 2018-02-14
09.05.17 12:37:02 pm
Cure Pikachu
User
Offline
Removing duplicates from a table?
Flacko, The Ultimate Lua Challenge has written:
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function unique(t)
local r = {}
local i = {}
for k,v in pairs(t) do
if not i[v] then
r[#r+1] = v
i[v] = 1
end
end
return r
end

a = unique({1,4,5,2,2,3,4})
for k,v in pairs(a) do print(v) end
09.05.17 12:40:31 pm
Promaster
User
Offline
Yes, removing duplicates from a table. Thank you for fast answer

How do i remove a random variable from testtable1 then?
edited 2×, last 09.05.17 02:48:13 pm
Patch 13.1! Updated. 2018-02-14
09.05.17 03:43:41 pm
Fraizeraust
Moderator
Offline
This one-liner should work flawlessly. Of course this should be put inside a loop if you want to execute
table.remove()
many times.
Code:
1
table.remove( testtable1, math.random(1, #testtable1) )

Just a brief explanation for you,
math.random()
picks randomly a value from the table and then it gets removed.
09.05.17 06:25:14 pm
Promaster
User
Offline
Removed question, ty for the answer Masea!
edited 2×, last 09.05.17 06:47:31 pm
Patch 13.1! Updated. 2018-02-14
09.05.17 06:44:59 pm
Masea
Super User
Offline
Code:
1
2
3
4
5
6
7
8
9
10
11
function randomt(table, number)
local t = {}
for k, v in pairs(table) do
if v == number then
table.insert(t, k)
end
end
if #t > 0 then
table.remove(table, math.random(#t))
end
end
Create and design your GUI easy and fast: GUI Framework (12) | Go deep of the darkness and try your intrepidity: Outlast 2 Modification (25)
09.05.17 06:48:04 pm
Promaster
User
Offline
Another question xDDDD
Is that possible to sort a table without using table.sort. And when you sort your table it sort in order to the number who comes first.

For example, i have a table.
Table = {3,1,3,1,3,2,1,2}

It sorts to
Table = {3,3,3,1,1,1,2,2}

I don't want to use Table.sort cause it will make the table -->

Table = {1,1,1,2,2,3,3,3}
Patch 13.1! Updated. 2018-02-14
09.05.17 07:12:32 pm
Masea
Super User
Offline
Try to give more table examples. I didn't get you what you want exactly.
Create and design your GUI easy and fast: GUI Framework (12) | Go deep of the darkness and try your intrepidity: Outlast 2 Modification (25)
09.05.17 07:24:26 pm
Promaster
User
Offline
For example, i have a table.
TestTable = {3,4,3,2,1,4,2,1,3}

I mean i want to sort a table in a order of the first number who comes first and then second one, and the third one etc....

The first number who appear in the table is "3" right. Then collect all the "3" in the table who comes first.
then the table should look like this
TestTable = {3,3,3,4,2,1,4,2,1}

then the second number is "4" to collect. then collect all the number "4" and the table should looks like
TestTable = {3,3,3,4,4,2,1,2,1}

then collect all number 2
TestTable = {3,3,3,4,4,2,2,1,1} then its done
Patch 13.1! Updated. 2018-02-14
09.05.17 07:42:49 pm
Masea
Super User
Offline
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
function differents(table)
local d = 0
local c
for k, v in pairs(table) do
if not c or c ~= v then
d = d + 1
c = v
end
end
return d
end

function tableif(t,s)
for k, v in pairs(t) do
if v == s then
return true
end
end
return false
end

function tablesort(table)
local t = {}
local c = false
for i = 1, differents(table) do
for k, v in pairs(table) do
if not c and not tableif(t,v) then
c = v
end
if v == c then
table.insert(t,v)
end
end
c = false
end
return t
end

differents
tells me how many different things in table.
tableif
tells me if selected number is in table. And finally,
tablesort
is what you are looking for.

I made it too quickly, it can be done with using fewer lines and might even not work. So test it, I'll always be here to help.
edited 2×, last 09.05.17 09:07:25 pm
Create and design your GUI easy and fast: GUI Framework (12) | Go deep of the darkness and try your intrepidity: Outlast 2 Modification (25)
09.05.17 07:49:13 pm
Promaster
User
Offline
Where do i put my "TestTable = {3,4,3,2,1,4,2,1,3}" in the code?
Patch 13.1! Updated. 2018-02-14
09.05.17 07:50:01 pm
Masea
Super User
Offline
tablesort(TestTable)
Create and design your GUI easy and fast: GUI Framework (12) | Go deep of the darkness and try your intrepidity: Outlast 2 Modification (25)
09.05.17 08:04:40 pm
Promaster
User
Offline
Got "attempt call field 'insert' (a nil value)"

Line 10
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function tablesort(table)
local t = {}
local c = false
for i = 1, differents(table) do
for k, v in pairs(table) do
if not c and not tableif(t,v) then
c = v
end
if v == c then
---->table.insert(t,v)<-----
end
end
c = false
end
return t
end
Patch 13.1! Updated. 2018-02-14
09.05.17 08:10:55 pm
Masea
Super User
Offline
Every Time or once?
Create and design your GUI easy and fast: GUI Framework (12) | Go deep of the darkness and try your intrepidity: Outlast 2 Modification (25)
09.05.17 08:23:49 pm
Promaster
User
Offline
The error spams everytime, like ms100
edited 1×, last 09.05.17 08:50:32 pm
Patch 13.1! Updated. 2018-02-14
09.05.17 09:06:42 pm
Masea
Super User
Offline
Looks like it's up to you because I can't see anything wrong in my code.

EDIT: Oh fuck, use this one. I used "table" as parameter name, shiet.
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function tablesort(tables)
local t = {}
local c = false
for i = 1, differents(tables) do
for k, v in pairs(tables) do
if not c and not tableif(t,v) then
c = v
end
if v == c then
table.insert(t,v)
end
end
c = false
end
return t
end

EDIT: I just tested it and it works.
Create and design your GUI easy and fast: GUI Framework (12) | Go deep of the darkness and try your intrepidity: Outlast 2 Modification (25)
09.05.17 09:33:27 pm
Promaster
User
Offline
Ty it works

I just went on a little problem on the sortation table function.
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
function differents(table)
local d = 0
local c
for k, v in pairs(table) do
if not c or c ~= v then
d = d + 1
c = v
end
end
return d
end

function tableif(t,s)
for k, v in pairs(t) do
if v == s then
return true
end
end
return false
end

function tablesort(tables)
local t = {}
local c = false
for i = 1, differents(tables) do
for k, v in pairs(tables) do
if not c and not tableif(t,v) then
c = v
end
if v == c then
table.insert(t,v)
end
end
c = false
end
return t
end

function unique(t)
local r = {}
local i = {}
for k,v in pairs(t) do
if not i[v] then
r[#r+1] = v
i[v] = 1
end
end
return r
end

When i am sorting a table with over 200 units in it. It will freeze the server for 1 second and then works again. Is there possible to avoid the big loop and avoid the freeze time for the server when i have over 200 units in a table?

When the table are over 200 variables, it starts lagging cause of the big loop from tablesort(tables). Is that possible to do it without a big loop to avoid the lagg?
edited 6×, last 09.10.17 04:37:03 pm
Patch 13.1! Updated. 2018-02-14
09.10.17 05:49:59 pm
User
Offline
http://unrealsoftware.de/forum_posts.php?post=411845&start=0#post411872

Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
TestTable = {3,4,3,6,2,1,6,4,2,6,6,1,3,6}

print(table.concat(TestTable, ", "))

function greetSort(tbl)
-- the smaller the value - the closer to the beginning of the sorted table a value must be
-- small values = first
-- large values = last
local nextValAt = {}
local itemsMoved, steps = 0, 0
for i = 1, #tbl do
steps = steps + 1
local item = tbl[i]
if not nextValAt[item] then
nextValAt[item] = i+1
--print("i=".. i, "New unknown value: ".. item, "New Rank: ".. i+1)

-- don't try to replace the currently existing same item
-- e.g: 5,5 - don't start the copying process of the latter 5
elseif item == tbl[nextValAt[item]] then
nextValAt[item] = nextValAt[item] + 1
--print("Item ".. item .." is in the correct pos. Increasing value of ".. item .." by 1 -> ".. nextValAt[item])
else
--print("i=".. i, "      known value: ".. item, "Inserting as #".. nextValAt[item], "Between ".. (tbl[nextValAt[item]-1] or "@") .." and ".. (tbl[nextValAt[item]] or "@"))
table.insert(tbl, nextValAt[item], item)
itemsMoved = itemsMoved + 1

repeat
nextValAt[item] = nextValAt[item] + 1
--print("Increasing value of ".. item .." by 1 -> ".. nextValAt[item])
if nextValAt[item] > i then break end
item = tbl[nextValAt[item]]
steps = steps + 1
until item == nil

table.remove(tbl, i+1)

end

end
print("steps: ".. steps, "itemsMoved: ".. itemsMoved)
end

greetSort(TestTable)
print(table.concat(TestTable, ", "))

It does exactly what you requested in the post, if you need to sort numbers or equal strings. Otherwise it needs a little tweaking.

It goes through the elements of the table and once it discovers an unknown element, this element receives a "rank" in the table (this rank is actually just the position in the table). If the same elements are discovered again in the table, it will be moved to the right of the chain of equal elements: 5,4,3,5 > 5,5,4,3

Performance: waaaay better than Masea's approach (@ Masea: you iterate the table as many times as many different types of elements exist if I read it correctly).
It's good on tables with many similar elements and gets a little worse if there are a lot of different elements.

I do realise there're better ways to do this, but I just had fun trying to do that within a single pass/single run of the for-loop. I think it would be faster if you create a separate table for each element and then glue them together into a big table.

You can benchmark them yourself, just don't forget to save Masea's final script in masea-sort.lua:
https://youtu.be/OlX8havmldo | 【東方】Bad Apple!! 【影絵】 in CS2D | Propaganda, Werbung für Waren (Reklame), Lehren und Ideen, besonders auf dem Gebiete der Politik, um Anhänger zu werben; z.B. Wahlpropaganda durch Versammlungen, Rundfunkreden, Plakate und Flugblätter
11.10.17 01:18:56 am
Vehk
User
Offline
Non-destructive function (returns a new table)

Destructive function (changes the input table) using table.sort
edited 2×, last 11.10.17 11:53:30 pm
12.10.17 02:37:46 am
Promaster
User
Offline
Thank you guys for helping me, tried you guys function, the problem are still there when i have 300 items+ in inventory. Solved this problem by adding max inventory space of 200 instead.

Patch 13.1! Updated. 2018-02-14
1 2
﻿