Table sorting

Is it possible to sort the internal table in ascending order or get in a loop?

{ --[[0000000002844C80]]
  4 = { --[[0000000002844210]]
    3 = { --[[00000000028442C0]]
      hash: [box_preview] = box@(-82, 700, 0),
    },
    2 = { --[[0000000002844DF0]]
      hash: [box_preview] = box@(-82, 700, 0),
    },
    4 = { --[[0000000002844DF0]]
      hash: [box_preview] = box@(-82, 700, 0),
    }
  },
  6 = { --[[0000000002842A20]]
    1 = { --[[0000000002844850]]
      hash: [box_preview_op] = box@(718, 700, 0),
    }
  }
}

for user_id, nodes in pairs(preview_nodes) do
  for pos, node in pairs(nodes) do
  end
end

i want get elemet with index 2,3,4 etc ascending

but i have 3,2,4 etc

I apologize in advance if my question is very simple. Well, I just can’t get used to lua :crying_cat_face:

You’re using ‘pairs’ to iterate with, which will always give them in semi-random order. You need to use ‘ipairs’ or a numerical ‘for’ loop (‘for i=1,10’, etc.) if you want them in order.

Of course the indices of your table don’t start at 1 and are not always consecutive, so ‘ipairs’ won’t work with it, and the numerical ‘for’ loop would take some wrangling. This seems like the real problem to me. How did you create this table? Why are the indices not 1, 2, 3, 4, etc.?

2 Likes

thanks for the answer but ipairs it doesn’t work

this is really a problem and it is not searched on the net

Correct, that’s what I said.

The problem is the table that you created. You made it in a way that is hard to deal with.

1 Like
			if preview_nodes[user_id] == nil then
				preview_nodes[user_id] = {[place] = prewiew}
			else
				preview_nodes[user_id][place] = prewiew
			end

but user_id and place - maybe random

Random indices for lists of items with random indices…but you want to iterate through them in order…you really like to make life difficult for yourself, eh? What are you trying to do with these, exactly?

If you want to keep ‘preview_nodes’ as a “map”, the way you have it, I suggest you keep track of the maximum index in each list, and iterate using that. In other words: every time you add or remove a ‘user_id’ to ‘preview_nodes’, check what the highest ‘user_id’ is, and remember that. That would make iterating in order very easy:

for i=1,highest_user_id do
    local nodes = preview_nodes[i]
    if nodes then
        -- do whatever you wanted to do
    end
end

Another way, would be to make ‘preview_nodes’ a simple list, (i.e. don’t use ‘user_id’ as the key) and sort it every time you change it, using table.sort.

-- Add new entries like this:
local user_preview = { id = user_id, places = {} }
table.insert(preview_nodes, user_preview)
-- then use table.sort with a custom sorting function.

-- so preview_nodes would look like this:
preview_nodes = {
    { id = 2, places = {...} },
    { id = 3, places = {...} },
    { id = 6, places = {...} }
}
-- instead of like this:
preview_nodes = {
    [2] = {...},
    [3] = {...},
    [6] = {...}
}

So then ‘ipairs’ would work:

for _,user_preview in ipairs(preview_nodes) do
    local user_id = user_preview.id
    for _,place in ipairs(user_preview.places) do
        -- do stuff
    end
end
5 Likes

Thank you very much for the answer.

I thought about this solution. Just didn’t want to complicate the code

Well, if you want to do more complicated things, then your code gets more complicated. :grinning_face_with_smiling_eyes: It’s best to not waste too much time trying to avoid the inevitable.

The first option is pretty darn simple. Just one math.max() when adding, and a little backwards search loop when removing (and only if it’s the last one).

1 Like