Подтвердить что ты не робот

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

У меня есть таблица значений key = > , которую я хотел бы сортировать в 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 нет необходимых инструментов (конечно), и встроенная среда слишком ограничена для меня, чтобы обойти ее.

Тем не менее, спасибо за вашу помощь, все!

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

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

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

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

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

Ответ 4

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

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

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

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

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

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

Ответ 5

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

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

Ответ 6

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

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

Я не знал о возможности сортировки массива с использованием метода, рекомендованного Kornel Kisielewicz.