Ассоциативная сортировка таблицы по значению в Lua

у меня есть таблица key => value, которую я хотел бы отсортировать в Lua. Ключи являются целыми числами, но не являются последовательными (и имеют значение). Единственной функцией сортировки Lua является table.sort, который рассматривает таблицы как простые массивы, отбрасывая исходные ключи и их связь с конкретными элементами. Вместо этого я бы, по сути, хотел иметь возможность использовать PHP asort()

6 ответов


Вы, кажется, что-то недопонимать. То, что у вас здесь есть ассоциативный массив. Ассоциативные массивы не имеют явного порядка на них, например, это только внутреннее представление (обычно отсортированное), которое их упорядочивает.

короче говоря -- в 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)

как сказал комель, вы имеете дело с ассоциативными массивами, которые не имеют гарантированного порядка.

Если вы хотите упорядочить ключ на основе его связанного значения, сохраняя при этом ассоциативную функциональность массива, вы можете сделать что-то вроде этого:

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    

хм, пропустил часть о том, что не может контролировать итерацию. там

но в lua обычно всегда есть способ.

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

Это начало. Теперь вам нужно будет заменить пары (), которые использует библиотека. Это может быть simples as pairs=my_pairs. Затем вы можете использовать решение по ссылке выше


массивы PHP отличаются от таблиц Lua.

  • массив PHP может иметь упорядоченный список пар ключ-значение.

  • таблица Lua всегда содержит неупорядоченный набор пар ключ-значение.

таблица Lua действует как массив, когда программист выбирает использовать целые числа 1, 2, 3,... в качестве ключей. Синтаксис языка и стандартные библиотечные функции, такие как table.sort предлагаем специальную поддержку таблицы с последовательными целочисленными ключами.

Итак, если вы хотите эмулировать массив PHP, вам придется представить его, используя список пар ключ-значение, который на самом деле является таблицей таблиц, но более полезно думать о нем как о списке пар ключ-значение. Передайте пользовательскую функцию" меньше, чем " в table.sort и все будет готово.

Б. Н. Lua позволяет вам mix последовательные целочисленные ключи с любыми другими типами ключей в то же самое таблицы и представления действенный. Иногда я использую эту функцию, обычно для пометки массива несколькими фрагментами метаданных.


приходя к этому через несколько месяцев, с тем же запросом. Рекомендуемый ответ, казалось, указывал на разрыв между тем, что требовалось, и тем, как это выглядит в LUA, но это не дало мне то, что я искал :- который был хэшем, отсортированным по ключу.

первые три функции на этой странице сделали, однако:http://lua-users.org/wiki/SortedIteration


пару лет назад я немного кодировал Lua, но я больше не владею им.

столкнувшись с подобной проблемой, я скопировал свой массив в другой массив с обратными ключами и значениями, А затем использовал sort на новом массиве.

Я не знал о возможности сортировки массива с помощью метода, рекомендованного Корнелем Киселевичем.