在 Lua 中按值关联排序表

Posted

技术标签:

【中文标题】在 Lua 中按值关联排序表【英文标题】:Associatively sorting a table by value in Lua 【发布时间】:2011-01-03 13:12:20 【问题描述】:

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

我有什么:

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

排序操作后我想要什么:

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

有什么想法吗?

编辑:根据答案,我假设这只是我正在使用的特定嵌入式 Lua 解释器的一个奇怪的怪癖,但在我的所有测试中,pairs()始终按照添加到表中的顺序返回表项。 (即上述两个声明的迭代方式不同)。

不幸的是,因为这不是正常行为,我似乎无法得到我需要的东西; Lua 没有内置(当然)必要的工具,而且嵌入式环境太有限,我无法解决它。

不过,谢谢大家的帮助!

【问题讨论】:

这两张表一模一样。 【参考方案1】:

你好像误会了什么。您在这里拥有的是associative array。关联数组没有明确的顺序,例如它只是对它们进行排序的内部表示(通常是排序的)。

简而言之——在 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)

【讨论】:

根据我的测试,这对 Lua 来说似乎不是真的。使用pairs() 迭代表时,顺序是稳定的,并且与添加项目的顺序相对应。此外,我没有选择更改数据存储方式的选项;我将结果输入到第 3 方库中,该库以“pairs() order”向用户显示项目。 pairs 以哈希顺序返回数据 - 它可能是稳定的 - 但它不是添加项目的顺序。来自 lua-users wiki “注意,当使用字典时,不能保证键存储在表中的顺序,因此不能保证使用 pair() 检索键的顺序。这个警告​​甚至适用于索引表的一部分,或者在根本不用作字典并且只有索引作为键的表中。” 顺便说一句,return a[0] &lt; b[0] 也咬了我太多次。 Lua 索引是从 1 开始的。 @Stavros - 天哪,这太奇怪了,以至于有人花了这么长时间才注意到它! 既然要比较字符串,不应该是return a[2] &lt; b[2]吗?【参考方案2】:

正如 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    

【讨论】:

你刚刚拯救了我的一天,几个小时以来一直在为桌子排序而苦苦挣扎。血腥的命令..【参考方案3】:

嗯,错过了无法控制迭代的部分。那里

但在 lua 中通常总有办法。

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

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

【讨论】:

【参考方案4】:

PHP 数组不同于 Lua 表。

一个 PHP 数组可能有一个键值对的有序列表

Lua 表始终包含 无序集 键值对。

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

所以,如果你想模拟一个 PHP 数组,你必须使用键值对列表来表示它,这实际上是一个表的表,但将其视为键列表会更有帮助-值对。将自定义的“小于”函数传递给table.sort,一切就绪。

注意Lua 允许您在 same 表中将连续整数键与任何其他类型的键混合 — 并且表示是有效的。我有时会使用这个功能,通常是用一些元数据标记一个数组。

【讨论】:

【参考方案5】:

几个月后,使用相同的查询。推荐的答案似乎指出了所需的内容与在 LUA 中的外观之间的差距,但它并没有让我得到我真正想要的东西:- 这是一个按 Key 排序的哈希。

然而,此页面上的前三个函数 DID:http://lua-users.org/wiki/SortedIteration

【讨论】:

但这恰恰是相反的问题:这个问题是按值排序。您的答案是按键排序【参考方案6】:

几年前我做了一点 Lua 编码,但我不再流利了。

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

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

【讨论】:

以上是关于在 Lua 中按值关联排序表的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JavaScript 中按值对地图进行排序?

在 Java 中按值映射自动排序

在火花对 RDD 中按值排序

如何在mysql中按值排序

在python中按值对defaultdict进行排序

在NodeJS中按值排序数组