web-dev-qa-db-ja.com

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()は常に、テーブルに追加された順序でテーブルアイテムを返します。 (つまり、上記の2つの宣言は異なる方法で反復されます)。

残念ながら、これは正常な動作ではないため、必要なものが取得できないようです。 Luaには必要なツールが(もちろん)組み込まれておらず、組み込み環境が制限されているため、私はそれを回避できません。

それでも、あなたの助けをありがとう、みんな!

21
Ben Blank

あなたは何かを誤解しているようです。ここにあるのは 連想配列 です。連想配列には明示的な順序はありません。それらを順序付けるのは内部表現(通常はソートされている)だけです。

つまり、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)
_
38

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    
9
Karl

うーん、繰り返しを制御できないという部分を逃しました。そこ

しかし、ルアにはいつも道があります。

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

それが始まりです。次に、ライブラリが使用するpairs()を置き換える必要があります。これは、pairs = my_pairsのような単純なものになる可能性があります。次に、上のリンクのソリューションを使用できます

6
sylvanaar

同じクエリで、数か月後にこれに来る。推奨される答えは、必要なものとこれがLUAでどのように見えるかの間のギャップを正確に示しているようですが、それは私が正確に何をしていたかを私に理解させませんでした:-これはキーでソートされたハッシュでした。

このページの最初の3つの関数DIDただし、: http://lua-users.org/wiki/SortedIteration

3
Phantomwhale

PHP配列はLuaテーブルとは異なります。

  • PHP配列には、キーと値のペアの順序付きリストを含めることができます。

  • Luaテーブルには常に、キーと値のペアの順不同のセットが含まれます。

プログラマが整数1、2、3、...をキーとして使用することを選択した場合、Luaテーブルは配列として機能します。 table.sortなどの言語構文と標準ライブラリ関数は、連続整数キーを持つテーブルを特別にサポートします。

したがって、PHP配列をエミュレートする場合は、キーと値のペアのリストを使用してそれを表す必要があります。これは実際にはテーブルのテーブルですが、考えるとより役立ちます。キーと値のペアのリストとして、カスタムの「小なり」関数をtable.sortに渡すと、すべての設定が完了します。

N.B. Luaではmix連続整数キーをsameテーブル内の他の種類のキーと組み合わせることができ、表現は効率的です。私は時々、この機能を使用して、通常、いくつかのメタデータで配列をタグ付けします。

3
Norman Ramsey

2、3年前にLuaのコーディングを少ししましたが、もう流暢ではありません。

同様の問題に直面したとき、キーと値を逆にした配列を別の配列にコピーし、新しい配列でsortを使用しました。

Kornel Kisielewiczが推奨する方法を使用して配列をソートする可能性を私は知りませんでした。

1
Carl Smotricz