Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend SU.collatedSort for complex table sorting #2105

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Omikhleia
Copy link
Member

@Omikhleia Omikhleia commented Sep 10, 2024

I noticed when working on #2082 : Our SU.collatedSort() works on list of strings only:

local names = {"Charlie", "Bob", "Alice"}
SU.collatedSort(names)
--  gives: {"Alice", "Bob", "Charlie"}

My own bad at the time (#1632)... but we can't use it to sort structured (key-value) tables with a comparison callback, as one would do with table.sort().

Of course there's a workaround, but it's a bit annoying (comparing for string equality, then performing a second ICU comparison for ordering)

So this PR is a proposal for supporting it, as:

-- Sort by age then name
local namesAndAges = { {name="Charlie", age=25}, {name="Bob", age=30}, {name="Alice", age=25} }
SU.collatedSort(namesAndAges, nil, function (a, b, stringCompare)
  if a.age < b.age then return true end
  if a.age > b.age then return false end
  return stringCompare(a.name, b.name) < 0
end)
-- gives { {name="Alice", age=25}, {name="Charlie", age=25}, {name="Bob", age=30} }

-- Sort by name then year
local namesAndYears = { {name="Alice", year=2005}, {name="Charlie", year=1995}, {name="Bob", year=1990}, {name="Alice", year=1995} }
SU.collatedSort(namesAndYears, nil, function (a, b, stringCompare)
  local nameCompare = stringCompare(a.name, b.name)
  if nameCompare < 0 then return true end
  if nameCompare > 0 then return false end
  return a.year < b.year
end)
-- gives { {name="Alice", year=1995}, { name = "Alice", year = 2005 }, {name="Bob", year=1990}, {name="Charlie", year=1995} }

In other terms:

  • Be less clever in the C code and just return -1, 0, 1 for (less, equal, greater)
  • Use a closure to pass ICU-enabled string comparison to the user callback.

@Omikhleia Omikhleia self-assigned this Sep 10, 2024
@Omikhleia Omikhleia added the enhancement Software improvement or feature request label Sep 10, 2024
@Omikhleia Omikhleia added this to the v0.15.6 milestone Sep 10, 2024
@Omikhleia
Copy link
Member Author

Omikhleia commented Sep 10, 2024

Oops sorry for the multiple push force... Was on wrongly rebased branch :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Software improvement or feature request
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

1 participant