11

Luaではpairsipairs同じ要素を異なる順序で繰り返すことができます。

> t = {[1]=1, [2]=2, [3]=3}
> for k,v in pairs(t) do print(k,v) end
2       2
1       1
3       3
> for k,v in ipairs(t) do print(k,v) end
1       1
2       2
3       3

C APIを使用する場合、テーブルを反復処理するためのツールは1つだけです。lua_next()pairs()関数は、上記の2-1-3の順序を生成するLua関数と非常によく似ています。

テーブルの整数キーを順番に反復処理するための効率的なCメソッド(ipairsのC APIバージョン)を探しています。

素朴に、私は考えました:

int tableLength = luaL_len(L, tableIndex);
for (i=0, i++, i>tableLength){   
    // if t[i] is not null ...
}

しかし、テーブルサイズが連続する整数キーの数と一致しない場合の潜在的なパフォーマンスの問題は不明です。

t = {[1]=1, [2]=2, [4]=4}     -- has a (reported) length of 4
t = {[1]=1, [2]=2, [40000]=4} -- has a (reported) length of 2

これが実際にipairsのやり方である場合、最後に見つかった整数キーでlua_nextの使用を開始して、整数キー部分を再度ウォークしないようにテーブルの残りの部分をウォークし続ける簡単な方法はありますか?そうすることで、いくつかの整数キーが2回表示される可能性はありますか?

4

2 に答える 2

9

nil キーを取得するまで rawgeti を使用します。

// Tabs is on top of stack
for ( int i=1 ; ; i++ ) {
    lua_rawgeti(L,-1,i);
    if ( lua_isnil(L,-1) ) {
        lua_pop(L,1);
        break;
    }
    /* Do something */
    lua_pop(L,1);
}

ソースを見ると、これが ipairs が内部で行っていることであることがわかります: http://www.lua.org/source/5.1/lbaselib.c.html#ipairsaux

于 2013-01-05T14:05:12.640 に答える
4
t = {[1]=1, [2]=2, [4]=4}     -- has a length of 4

さて、そこにあなたの問題があります。長さは4ではありません。そう思うかもしれませんし、#t4を返すかもしれません。しかし、Lua APIに関する限り、このテーブルの長さは未定義です。

Lua 5.1の状態

テーブルtの長さは、t [n]がnilでなく、t [n + 1]がnilであるように、任意の整数インデックスnとして定義されます。さらに、t 1がnilの場合、nはゼロになる可能性があります。1から特定のnまでのnil以外の値を持つ通常の配列の場合、その長さは、最後の値のインデックスであるnとまったく同じです。配列に「穴」(つまり、他の非nil値の間のnil値)がある場合、#tは、nil値の直前にある任意のインデックスにすることができます(つまり、そのようなnil値を最後と見なすことができます)。アレイの)。

Lua 5.2はかなり明確です:

テーブルtの長さは、テーブルがシーケンスである場合、つまり、正の数値キーのセットが整数nに対して{1..n}に等しい場合にのみ定義されます。その場合、nはその長さです。次のようなテーブルに注意してください

 {10, 20, nil, 40}

キー4はあるが、キー3はないため、はシーケンスではありません(したがって、セット{1..n}がそのテーブルの正の数値キーのセットと等しくなるようなnはありません)。ただし、数値以外のキーは、テーブルがシーケンスであるかどうかに干渉しないことに注意してください。

ただし、どちらの場合も、長さは未定義です。

于 2013-01-04T00:53:36.323 に答える