以 Lua 中的值为标准对表进行关联排序

我有一张键值对表,想在 Lua 中对其进行排序。键都是整数,但不连续(并且有意义)。Lua 的唯一排序函数似乎是table.sort,它将表视为简单的数组,丢弃原始键及其与特定项目的关联。相反,我基本上想使用 PHP 的 asort() 函数。

我有什么:

items = {
    [1004] = "foo",
    [1234] = "bar",
    [3188] = "baz",
    [7007] = "quux",
}

排序操作后我想要的:

items = {
    [1234] = "bar",
    [3188] = "baz",
    [1004] = "foo",
    [7007] = "quux",
}

有什么想法吗?

编辑:根据答案,我将假定它只是我正在使用的特定嵌入式 Lua 解释器的奇怪瑕疵,但在我所有的测试中,pairs()始终以它们添加到表中的顺序返回表项。(即上面的两个声明会遍历不同)。

不幸的是,因为这不是正常行为,看起来我无法得到我需要的;Lua 没有必要的内置工具(当然),并且嵌入式环境过于有限,无法绕过它。

不过,还是谢谢大家的帮助!

原文链接 https://stackoverflow.com/questions/2038418

点赞
stackoverflow用户233522
stackoverflow用户233522

你似乎误解了一些东西。你现在有的是一个关联数组。关联数组之间没有明确的顺序,例如,只有内部表示(通常是排序的)才排序。

简而言之,在 Lua 中,你发布的这两个数组是 相同的

你想要的是这样的表示方式:

items = {
    {1004, "foo"},
    {1234, "bar"},
    {3188, "baz"},
    {7007, "quux"},
}

虽然现在你不能通过索引获取它们(它们被索引为 1、2、3、4,但你可以创建另一个索引数组),但是你可以使用 table.sort 对它们进行排序。

排序函数如下:

function compare(a,b)
  return a[1] < b[1]
end

table.sort(items, compare)
2010-01-10 20:17:59
stackoverflow用户172211
stackoverflow用户172211

我在几年前做过一点点 Lua 编程,但现在已经不太熟练了。

当遇到类似的问题时,我将数组复制到另一个数组中,然后将键和值颠倒,接着在新数组上使用 sort 方法。

我不知道可以使用 Kornel Kisielewicz 推荐的方法对数组进行排序。

2010-01-10 20:48:41
stackoverflow用户151501
stackoverflow用户151501

尝试使用 Lua 中的有序关联表

哦,我没注意到不能控制迭代这一点。不过,在 Lua 中通常总有办法。

http://lua-users.org/wiki/OrderedAssociativeTable

这是一个开始。现在,你需要替换库使用的 pairs() 函数。这可能只需要把 pairs=my_pairs。然后,你可以使用上面链接中的解决方案。

2010-01-10 20:57:32
stackoverflow用户41661
stackoverflow用户41661

PHP 数组与 Lua 表格不同。

  • PHP 数组可以有 有序 的键值对列表。

  • Lua 表格总是包含 无序 的键值对集合。

当程序员选择使用整数 1、2、3 等作为键时,Lua 表格就像一个数组一样。语言语法和标准库函数,例如 table.sort,为具有连续整数键的表格提供了特殊支持。

因此,如果要模拟 PHP 数组,必须使用键值对列表来表示它,这实际上是一个表格的表格,但将其视为键值对列表更有帮助。向 table.sort 传递自定义的“小于”函数,然后就可以设置好了。

注意:Lua 允许您在 相同的 表格中 混合使用 连续整数键和其他任何类型的键——并且表示效率很高。我有时会使用此功能,通常将一些元数据与数组标记。

2010-01-11 03:46:21
stackoverflow用户82663
stackoverflow用户82663

几个月后再来,有同样的疑问。建议的答案似乎指出了所需的东西与LUA中的实际情况之间的差距,但它并没有完全提供我需要的答案——即一个按键排序的哈希表。

不过,这个页面上的前三个函数确实提供了我需要的:http://lua-users.org/wiki/SortedIteration

2011-05-12 12:15:17
stackoverflow用户377446
stackoverflow用户377446

正如Komel所说,你正在处理无保证排序的关联数组。

如果你想基于相关值进行键排序,同时保留关联数组功能,可以这样做:

function getKeysSortedByValue(tbl, sortFunction)
  local keys = {}
  for key in pairs(tbl) do
    table.insert(keys, key)
  end

  table.sort(keys, function(a, b)
    return sortFunction(tbl[a], tbl[b])
  end)

  return keys
end

items = {
    [1004] = "foo",
    [1234] = "bar",
    [3188] = "baz",
    [7007] = "quux",
}

local sortedKeys = getKeysSortedByValue(items, function(a, b) return a < b end)

sortedKeys是{1234,3188,1004,7007},你可以这样访问你的数据:

for _, key in ipairs(sortedKeys) do
  print(key, items[key])
end

结果:

1234     bar
3188     baz
1004     foo
7007     quux
2014-07-04 02:16:44
stackoverflow用户1120127
stackoverflow用户1120127

所提议的compare函数可以工作,但只有在第一列中的值是唯一的情况下才有效。

以下是增强版的 compare 函数,以确保如果实际列的值相等,则从下一列中取值进行评估......

如果{1234,"baam"} < {1234,"bar"}true,则包含“baam”的数组将插入到包含“bar”的数组之前。

local items = {
    {1004"foo" },
    {1234"bar " },
    {1234"baam" },
    {3188"baz " },
    {7007"quux" },
}

local function compare(a,b)
    for inx = 1,#a do
        - -打印("A " .. inx .." ".. a [inx] )
        - -打印("B " .. inx .." ".. b [inx] )

        if a [inx] == b [inx] and a [inx + 1] <b [inx + 1] then
            返回true
        elseif a [inx] ~ = b [inx] and a [inx] <b [inx] == true then
            返回true
        其他
            返回false
        结束
    end
    返回false
end

table.sort(items,compare)
2022-05-13 10:15:18