編集:再帰的なソリューションでは、作成できる配列のサイズに制限があるため、
PJ@GitHubライブラリで別のソリューションを作成しました。これは疑似インスタント速度で実行され、任意のサイズ、任意の構造、任意のブランチの任意の次元の多次元配列を作成および管理できます。また、事前入力をシミュレートしたり、カスタムデザインのノードオブジェクトを使用したりすることもできます。ここでそれをチェックしてください:https://github.com/PimpTrizkit/PJs/wiki/14.-Complex-Multireflection-Object--(pCMO.js)
jfabrizioのソリューションの修正バージョンを使用する:
function createNDimArray(dimensions) {
var t, i = 0, s = dimensions[0], arr = new Array(s);
if ( dimensions.length < 3 ) for ( t = dimensions[1] ; i < s ; ) arr[i++] = new Array(t);
else for ( t = dimensions.slice(1) ; i < s ; ) arr[i++] = createNDimArray(t);
return arr;
}
使用法:
var arr = createNDimArray([3, 2, 3]);
// arr = [[[,,],[,,]],[[,,],[,,]],[[,,],[,,]]]
console.log(arr[2][1]); // in FF: Array [ <3 empty slots> ]
console.log("Falsy = " + (arr[2][1][0]?true:false) ); // Falsy = false
これはかなり速いことがわかりました。JavascriptでN次元配列を生成するのが可能な限り最速の方法であると言っても過言ではありません。上記のこのリファクタリングでは、速度がかなり向上しました。しかし、もちろん、最高の速度向上は事前充填を行わなかったことによるものです。このバージョンでは、アレイは事前に入力されていません。最後のレベルが単なる空の配列である、Nsの長さの完全に作成されたN次元配列のみを返します。arr[x][y][z]?arr[x][y][z]:null
あなたが本当に価値を必要とするならば、それで十分であることを願っていnull
ます。それは私の使用のためです。:)
事前入力が必要な場合は、彼の元のバージョンを使用してください。
そして、あなたが私がしたことを本当に気にしないのなら、その後、読書を停止します。
もっとオタクの話をしたいですか?そこから学んでいる人のための再帰について少し。さて、ここに戦術があります。深い再帰を行うときは、最終レベルを念頭に置いてください。ほとんどの作業が行われる場所です。この場合、文字通りN番目の次元です。これがあなたの「ペイロード」であり、残りはロジスティクスです。jfabの関数では、に到達dimensions.length
する1
と、最後の次元、N番目の次元に到達し、ペイロードを実行します。これは、nullの配列、または私の場合は空の配列を作成することです。再帰が非常に深くなるため、各次元は最後の次元の要因になります。N次元に到達するまでに、多くの関数呼び出しが発生し、コンピューターのロジスティクスが煩雑になります。そして、N番目の次元で、基本再帰関数を呼び出します(createNDimArray
私たちの場合)ロジスティクスよりもペイロードの方が多くなります。さて、jfabの元のソリューションと同様に、ペイロードの実行を(可能であれば)再帰で最初に行うこととして配置することは、特に単純な場合は、通常は良いことです。ここでは、ペイロードを最終的な2D配列の構築にします(単に1D配列new Array()
のみを返すのではなく)。そうすれば、このレベルで過剰な量の関数呼び出しを行う必要がなくなります。もちろん、配列を事前に入力する場合は、このショートカットが常に役立つとは限りません。しかし、もっと重要なことは、アレイを事前に入力することが適切なペイロードになるということです。しないでN次元のすべてのアイテムにアクセスすると、効果的に削除されました。そうすれば、関数呼び出しのレベルが1つ少なくなり、基本的にN番目の次元のペイロードは実際にはN-1番目の次元で実行されます。また、を配信するためだけに再帰関数を再度呼び出すことはありませんnew Array()
。残念ながら、new Array(x)
(一般的に)への呼び出しはそれをそのように見ていません。その実行時間は、が大きくなると長くなりx
ます。これは事実上、Nth Dimensionのすべてのアイテムにアクセスしていますが、今では1回だけ、ネイティブコードを使用して、タイトで軽いループにラップされています。ここで、これはcreateNDimArray
N> 1でのみ呼び出すことができる必要があります。つまり、1D配列の作成には使用されません。理論的には、より大きなNが必要になり、最後にさらに多くの次元を展開できます。基本的に、の行は次のif ( dimensions.length < 3 )
ようになります< 4
または< 5
、そこにあるループの周りにさらに多くのループをラップするfor
必要があり、それぞれに独自のvar
sのセットが必要になります---過剰な機能を取引しているため、すべてがどれほど効率的かはわかりません同様のアイデアでスペース/操作を呼び出してスタックしますが、埋め込まれていますfor
ループ---しかし、Nが常に特定のレベルを上回っていることがわかっている場合、または最終的な次元に対してのみである場合は、一部の環境を高速化できると思います。ここのように、私は最後の2つの次元でそれを行いました。しかし、展開しすぎると、ペイロード自体がクマになります。テストだけがそれが価値があるかどうかを教えてくれます。スタックスペースには限りがあるようですが、より多くの展開でより大きな配列を作成できたのを覚えていると思います。配列を作成できるサイズには制限があります。そして、N番目のレベルで各アイテムを呼び出す再帰ソリューションは、私がそうする場合、最低の制限がありました..思い出してください..正しく....はるかに低くなりました。
彼のソリューションを改訂する次の部分は単なるロジスティクスであり、過剰なブロックとコードを取り除くための単純なリファクタリングでした。すべてのvar
作業に参加して、それだけです。arr
戻る必要があるので、ループが終了すると、var
最初にすべての作業を1行で実行することもできますが、幸いなことに、4つvar
のうち3つは同じ初期化を行います。,
可能であれば、Javascriptはと結合するときにコードを最適化できることを忘れないでください。これにより、コードも小さくなります。
PT