SciTE 排序选择工具:带有前导空格的数字未按预期排序
SciTE sort selection tool : numbers with leading spaces are not sorted as expected
SciTE 编辑器带有嵌入式 Lua 脚本引擎,可以访问编辑器的文本缓冲区。这使得使用在 Lua 中编程并从工具菜单启动的工具扩展 SciTE 的功能成为可能。可从此处获得此类工具之一:
http://lua-users.org/wiki/SciteSortSelection
是一种按字母顺序对所选行进行排序的工具。
令我恼火的是 was/is 它不会按数字顺序对包含数字的行进行排序,而是像这样:
1
111
2
222
3
333
我希望的地方:
1
2
3
111
222
333
Google 和 Co. 在这里没有太大帮助,因为据我所知,还没有在线解决此问题的方法。查找和深入理解 table.sort() 的 Lua 文档也不是那么容易。因此,知识渊博的 Lua 程序员的问题是,修补现有 Lua 脚本代码的最佳方法是什么,以便数字(以及在前导空格的情况下带有文本的行)被排序为符合预期并且此任务的 Lua 代码运行得如此之快,以至于即使对大文件(50 MByte 或更多)进行排序也不会花费太多时间?
你的期望是错误的。你说算法应该按字母顺序对文本进行排序,而这正是它所做的。
因为Lua“11”小于“2”。
我想你会同意 "aa" 应该出现在 "b" 之前,这几乎是一回事。
如果您想更改文本的排序方式,您必须提供自己的函数。
Lua 参考手册说:
table.sort (list [, comp])
Sorts list elements in a given order, in-place, from list[1] to
list[#list]. If comp is given, then it must be a function that
receives two list elements and returns true when the first element
must come before the second in the final order (so that, after the
sort, i < j implies not comp(list[j],list[i])). If comp is not given,
then the standard Lua operator < is used instead.
Note that the comp function must define a strict partial order over
the elements in the list; that is, it must be asymmetric and
transitive. Otherwise, no valid sort may be possible.
The sort algorithm is not stable: elements considered equal by the
given order may have their relative positions changed by the sort.
因此您可以自由实现自己的 comp 函数来更改排序。
默认情况下table.sort(list)
以升序排列列表。
要使其按降序排序,请调用:
table.sort(list, function(a,b) return a > b end)
如果你想以不同的方式对待数字,你可以这样做:
t = {"111", "11", "3", "2", "a", "b"}
local function myCompare(a,b)
local a_number = tonumber(a)
local b_number = tonumber(b)
if a_number and b_number then
return a_number < b_number
end
end
table.sort(t, myCompare)
for i,v in ipairs(t) do
print(v)
end
这会给你输出
2
3
11
111
a
b
当然这只是一个快速简单的例子。更好的实现取决于您。
下面是我自己终于想出来的。这肯定是一个快速而肮脏的解决方案,它会减慢已经很慢的速度
(与 jEdit [插件]->[文本工具]->[排序行] 或 bash 命令行 'sort -g' 相比)
对巨大的文本行缓冲区进行排序的过程,但它至少可以使用并按预期工作。为了完整起见,我的 Lua SciTE 启动脚本中目前存在的整个代码部分:
-- =============================================================================
-- Sort Selected Lines (available in MENU -> Tools):
-- -----------------------------------------------------------
-- Specify in .SciTEUser.properties:
-- command.name.2.*=# Sort Selected Lines '
-- command.subsystem.2.*=3
-- command.mode.2.*=savebefore:no
-- command.2.*=SortSelectedLines
-- # command.shortcut.2.*=Ctrl+2 # Ctrl+2 is DEFAULT for command.2.*
function lines(str)
local t = {}
local i, lstr = 1, #str
while i <= lstr do
local x, y = string.find(str, "\r?\n", i)
if x then t[#t + 1] = string.sub(str, i, x - 1)
else break
end
i = y + 1
end
if i <= lstr then t[#t + 1] = string.sub(str, i) end
return t
end
-- It was an annoying for me that using table.sort(buffer) in Lua
-- didn't sort numbers with leading spaces in their numerical order.
-- Using following comparison function helps to avoid that problem:
function compare(a,b)
return a:gsub(" ", "0") < b:gsub(" ", "0")
-- If 'compare' is not used ( table.sort(buf) )
-- Lua uses implicit for sorting (see Lua tutorial):
-- return a < b
-- so changing the provided return statement to this above
-- would be enough to restore sorting to how it was before
end
function SortSelectedLines()
local sel = editor:GetSelText()
if #sel == 0 then return end
local eol = string.match(sel, "\n$")
local buf = lines(sel)
table.sort(buf, compare)
--table.foreach (buf, print) --used for debugging
local out = table.concat(buf, "\n")
if eol then out = out.."\n" end
editor:ReplaceSel(out)
end
-- ---------
-- :Sort Selected Lines
-- -----------------------------------------------------------------------------
SciTE 编辑器带有嵌入式 Lua 脚本引擎,可以访问编辑器的文本缓冲区。这使得使用在 Lua 中编程并从工具菜单启动的工具扩展 SciTE 的功能成为可能。可从此处获得此类工具之一:
http://lua-users.org/wiki/SciteSortSelection
是一种按字母顺序对所选行进行排序的工具。 令我恼火的是 was/is 它不会按数字顺序对包含数字的行进行排序,而是像这样:
1
111
2
222
3
333
我希望的地方:
1
2
3
111
222
333
Google 和 Co. 在这里没有太大帮助,因为据我所知,还没有在线解决此问题的方法。查找和深入理解 table.sort() 的 Lua 文档也不是那么容易。因此,知识渊博的 Lua 程序员的问题是,修补现有 Lua 脚本代码的最佳方法是什么,以便数字(以及在前导空格的情况下带有文本的行)被排序为符合预期并且此任务的 Lua 代码运行得如此之快,以至于即使对大文件(50 MByte 或更多)进行排序也不会花费太多时间?
你的期望是错误的。你说算法应该按字母顺序对文本进行排序,而这正是它所做的。
因为Lua“11”小于“2”。 我想你会同意 "aa" 应该出现在 "b" 之前,这几乎是一回事。
如果您想更改文本的排序方式,您必须提供自己的函数。
Lua 参考手册说:
table.sort (list [, comp])
Sorts list elements in a given order, in-place, from list[1] to list[#list]. If comp is given, then it must be a function that receives two list elements and returns true when the first element must come before the second in the final order (so that, after the sort, i < j implies not comp(list[j],list[i])). If comp is not given, then the standard Lua operator < is used instead.
Note that the comp function must define a strict partial order over the elements in the list; that is, it must be asymmetric and transitive. Otherwise, no valid sort may be possible.
The sort algorithm is not stable: elements considered equal by the given order may have their relative positions changed by the sort.
因此您可以自由实现自己的 comp 函数来更改排序。
默认情况下table.sort(list)
以升序排列列表。
要使其按降序排序,请调用:
table.sort(list, function(a,b) return a > b end)
如果你想以不同的方式对待数字,你可以这样做:
t = {"111", "11", "3", "2", "a", "b"}
local function myCompare(a,b)
local a_number = tonumber(a)
local b_number = tonumber(b)
if a_number and b_number then
return a_number < b_number
end
end
table.sort(t, myCompare)
for i,v in ipairs(t) do
print(v)
end
这会给你输出
2
3
11
111
a
b
当然这只是一个快速简单的例子。更好的实现取决于您。
下面是我自己终于想出来的。这肯定是一个快速而肮脏的解决方案,它会减慢已经很慢的速度
(与 jEdit [插件]->[文本工具]->[排序行] 或 bash 命令行 'sort -g' 相比)
对巨大的文本行缓冲区进行排序的过程,但它至少可以使用并按预期工作。为了完整起见,我的 Lua SciTE 启动脚本中目前存在的整个代码部分:
-- =============================================================================
-- Sort Selected Lines (available in MENU -> Tools):
-- -----------------------------------------------------------
-- Specify in .SciTEUser.properties:
-- command.name.2.*=# Sort Selected Lines '
-- command.subsystem.2.*=3
-- command.mode.2.*=savebefore:no
-- command.2.*=SortSelectedLines
-- # command.shortcut.2.*=Ctrl+2 # Ctrl+2 is DEFAULT for command.2.*
function lines(str)
local t = {}
local i, lstr = 1, #str
while i <= lstr do
local x, y = string.find(str, "\r?\n", i)
if x then t[#t + 1] = string.sub(str, i, x - 1)
else break
end
i = y + 1
end
if i <= lstr then t[#t + 1] = string.sub(str, i) end
return t
end
-- It was an annoying for me that using table.sort(buffer) in Lua
-- didn't sort numbers with leading spaces in their numerical order.
-- Using following comparison function helps to avoid that problem:
function compare(a,b)
return a:gsub(" ", "0") < b:gsub(" ", "0")
-- If 'compare' is not used ( table.sort(buf) )
-- Lua uses implicit for sorting (see Lua tutorial):
-- return a < b
-- so changing the provided return statement to this above
-- would be enough to restore sorting to how it was before
end
function SortSelectedLines()
local sel = editor:GetSelText()
if #sel == 0 then return end
local eol = string.match(sel, "\n$")
local buf = lines(sel)
table.sort(buf, compare)
--table.foreach (buf, print) --used for debugging
local out = table.concat(buf, "\n")
if eol then out = out.."\n" end
editor:ReplaceSel(out)
end
-- ---------
-- :Sort Selected Lines
-- -----------------------------------------------------------------------------