Comments (2)
Sol tables are just lua tables. And lua tables are not guaranteed to be ordered, so the assumption in step 1 that the code creates the table with specific order is incorrect. As I understand, tables are basically hash maps.
The order of the assignments in a constructor is undefined.
The for_each documentation tells that it does not guarantee order.
The iterators you use to walk through a sol::table are NOT guaranteed to iterate in numeric order
Furthermore, in lua you can only A) iterate through a table by specifying the keys to iterate yourself and accessing that specific key in a loop, B) by iterating from 1 up to the first absent index (ipairs), C) by looping through all keys in the table with pairs which does not guarantee order (pairs calls next). for_each in sol is the same as pairs so it will never have guaranteed order even if the data would be ordered, and from the documentation of next
which pairs uses:
The order in which the indices are enumerated is not specified, even for numeric indices.
To collect all of this together, what you can do is create an ordered list containing the data instead and iterate through it using ipairs (or in sol, just get length and iterate from 1 to length):
// myTable = {
// { first = 1 },
// { second = 2 },
// { third = 3 },
// }
sol::table myTable = lua.create_table();
myTable[1] = lua.create_table_with(1, "first", 2, 1);
myTable[2] = lua.create_table_with(1, "second", 2, 2);
myTable[3] = lua.create_table_with(1, "third", 2, 3);
for (int i = 1, count = myTable.size(); i <= count; ++i) {
lua["print"](i, myTable[i], myTable[i][1], myTable[i][2]);
}
This is a lot less efficient and inconvenient overall but it guarantees order. There are of course other options, like creating your own data structure, or exposing some kind of C++ data structure to lua depending on what you need. On that vein, if you want an easy way for ordering while having a regular map, you could track the insertions and deletions from the table in a separate list. However, seems that for_each in sol does not check the metamethod __pairs
🤔. We could expose the order table and iterate through it instead.
-- Define the table with metatable
function createTrackedTable()
local data = {}
local order = {}
local mt = {
__newindex = function(t, k, v)
if v == nil then
-- Remove key from data and order if the value is nil
rawset(data, k, nil)
for i, key in ipairs(order) do
if key == k then
table.remove(order, i)
break
end
end
else
-- Add new key-value pair to data and key to order
if rawget(data, k) == nil then
table.insert(order, k)
end
rawset(data, k, v)
end
end,
__index = data,
__pairs = function(t)
local i = 0
local function iter(data, oldk)
i = i + 1
local k = order[i]
if k then
return k, data[k]
end
end
return iter, data, nil
end,
order = order,
}
return setmetatable({}, mt)
end
-- Usage
local trackedTable = createTrackedTable()
-- Insert elements
trackedTable["first"] = 1
trackedTable["second"] = 2
trackedTable["third"] = 3
-- Print elements in their insertion order
for k, v in pairs(trackedTable) do
print(k, v)
end
-- Remove element
trackedTable["second"] = nil
-- add it back in
trackedTable["second"] = 2
-- Print elements in their insertion order
for k, v in pairs(trackedTable) do
print(k, v)
end
// Create a tracked table
sol::function createTrackedTable = lua["createTrackedTable"];
sol::table trackedTable = createTrackedTable();
// Insert elements into the tracked table
trackedTable["first"] = 1;
trackedTable["second"] = 2;
trackedTable["third"] = 3;
// Access the order table
sol::table mt = lua["getmetatable"](trackedTable);
sol::table order = mt["order"];
// Iterate over the order table to print elements
for (int i = 1, count = order.size(); i <= count; ++i) {
sol::object key = order[i];
lua["print"](key, trackedTable[key]);
}
In general only lists, stacks, queues and similar data structures have insertion order preserved. Maps and sets order the data on its own, based on the keys or values usually, so they may not suit your needs if you require insertion order being preserved. I would say that JavaScript is quite unique in its implementation of a map style structure with insertion order when iterated (ref). Not sure I have seen anything similar elsewhere yet. 👀
from sol2.
@Rochet2 thank you very much for the technical explanation and support. I have continued to read the documentation of both Lua and Sol2 and will try to implement one of your proposed methods to achieve separate sorting. Basically, even if I do not respect the insertion order I need the keys to always be in a certain order before conversion to Json.
In general, I am well aware of the pattern to be followed for the final result in terms of key sorting, but I am trying to get something that scales well for future software modifications and customization of results 👍🏻
from sol2.
Related Issues (20)
- Crash during destruction when using meta_function::new_index and coroutines
- Accessing table field with the wrong user type causes a segmentation fault
- Cannot directly bind b2Vec2 to a table entry HOT 1
- SOL_BASE_CLASSES / SOL_DERIVED_CLASSES should be mentioned in the documentation
- Generating definition files
- Why sol3 is slower than Luabridge3 when both using LuaJIT, HOT 1
- add_package_loader without lua_CFunction
- Handling opaque C pointers
- confusing behaviour of environments for lua > 5.2 HOT 1
- Error in emplace method
- const correctness of C++ object passed to sol::protected_function
- Using libraries which add searchers/loaders from C++ HOT 1
- Getting compilation error when registering type HOT 3
- compilation issue: no member named 'construct' HOT 4
- Add mirrors for downloading lua
- SOL_SAFE_FUNCTION_CALLS does not recognize derived classes HOT 5
- Clang 18 support HOT 1
- How to secure such a pointer?
- Impossible to create an inner usertype/enum in a usertype
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sol2.