Grouping similar adjacent values in a table

This is something I can’t figure out.
Let’s say I have a table;

a = {0, 0, 0, 5, 5, 2, 2, 2, 0, 3, 3, 3, 3}

and I want to convert it to this;

b = {
    {0, 0, 0},
    {5, 5},
    {2, 2, 2}
    {0}
    {3, 3, 3, 3}
}

How would I go about doing this? Thank’s for your time.

1 Like

What exactly are you trying to accomplish here? You could do this using a transition table that specifies the prevalence of different unique values. This is similar to a radix sort. The idea is to count the times that each unique value appears, store that value in a table, then reconstruct a new table with that information. There is most likely a better way to do this. What is it for?

2 Likes

I don’t quite get what you mean.

Why do you need to do this exactly? If you tell me what it is for I could probably help you find a better way to do it.

1 Like

I have like a robot that raycasts 10 studs ahead and gets the first track that it hit’s, then it gets the angle between the previous track and the current track and stores it in a table, similar to table a (I copy a script I made and then paste it into the command bar). I want to group the similar angles so I can create a smooth bank on a curve, after I can get a new table like b I want to make the banking angle smooth, so if I get this table;

local b = {
    {0, 0, 0},
    {2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
    {1, 1, 1, 1, 1},
    ...
}

and change it to

local b = {
    {0, 0, 0},
    {0.5, 1, 1.5, 2, 2, 2, 2, 2, 1.75, 1.5, 1.25},
    {1, 1, 1, 1, 1},
    ...
}

Here is an image of the tracks

Another thing to mention, I am using archimedes 2.4 plugin by Scriptos and each track is 3 studs long

Ok here you go:

-- First we construct a temporary storage
local temp = {} -- This will store the number of occurrences of each number in 'a'
for i = 1, #a do
   if not temp[i] then -- If this is the first time we find a number, add it into temp and set its occurrence to 1
      temp[a[i]] = 1
   else -- Otherwise, add 1 for each new occurence
      temp[a[i]] += 1
   end
end

-- Now we will construct 'b'
local b = {}
local x = 1
for n, v in pairs(temp) do
   b[x] = {} -- Create a table within 'b' for each unique 'n', which is a unique number in 'a'
   x += 1

   for i = 1, v do -- Run a loop to copy that number into the table the same amount of times it appears in 'a', as stored in 'temp'
      b[x][i] = n
   end
end
1 Like

Could you explain each line please?

I updated my answer with comments

1 Like

Does it still work if the number is repeated twice?

like {0, 0, 0, 1, 1, 1, 0, 0, 0}

It will radix sort the numbers, so if the number appears twice in two different locations, then it will be combined.

1 Like

If you don’t want the numbers to repeat use this alternative:

local b = {}
local last
local x = 0
for i = 1, #a do
   if a[i] == last then
     b[x][#b[x]+1] = a[i]
   else
      x += 1
      b[x] = {}

      b[x][1] = a[i]
      last = a[i]
   end
end
1 Like

It’s not going to work as-is. Let me fix it

1 Like

There’s an error on line 20 ‘attempt to index nil with number’

Ok I rewrote it. See if this works. I haven’t tested it. (I edited my last code comment)

1 Like

Also don’t you think there would be an easier way to do this by slicing the table and putting them as a nested table in b

I didn’t realize at first that you needed it to work with repeat number groups. Originally it required a temp variable to store occurrences but now it doesn’t. This should be the most straightforward solution.

1 Like

Slicing or your solution (I tested it and it works)

My solution. I’m not sure what you mean by slicing.

1 Like