2016-06-22 5 views
1

私の別の質問では、誰かがn番目のネストされた配列を1つの配列に平坦化する方法について本当にクールなソリューションを投稿しました。私は長いチャットを始めたいとは思っていなかったので、このコードが何をしているかをまだ十分に理解していないので、私は尋ねると思った。配列の理解コードを平坦化

私の印象は、この場合、配列の長さが2で、whileループでは1になります。次に、array[1]が配列であることを確認します。それで私たちは進めます。ここで私はちょっと混乱しているところです。ネストされた配列に入るためにflatten関数を再度呼び出すと信じていますが、私はまだ推論にはぼんやりしています。その後、array[1]をスライスしてスライスしますが、ここではスライシングしないと、とにかくarray[l]全体が得られますか? slice()にはパラメータがないので、0番目の位置から最後に移動するためです。

function flatten(array) { 
    var l = array.length, temp; 
    while (l--) { 
     if (Array.isArray(array[l])) { 
      flatten(array[l]); 
      temp = array[l].slice(); 
      temp.unshift(1); 
      temp.unshift(l); 
      [].splice.apply(array, temp); 
     } 
    } 
} 


var array = [['1', '2', '3'], ['4', '5', ['6'], ['7', '8']]]; 

flatten(array); 

console.log(array); 

https://jsfiddle.net/curw7mdp/

答えて

1

だから私はあなたが再帰の基本を理解仮定するつもりです。私は行ごとにあなたを歩いて行きます。

var l = array.length, temp; 

lは、配列の長さに等しいと宣言し、tempを宣言します。

while (l--) 

これは、(前にそれを行う-L-とは対照的に)ループの反復後L をデクリメントします。

if (Array.isArray(array[l])) 

これは、配列の '1番目の要素が別の配列であるかどうかを確認します。これは、この要素がフラットでないことを意味するため、重要です。

flatten(array[l]); 

これは面白いところですが、この関数は再帰的に自分自身を呼び出すので、サブ配列をトラバースできるようになります。サブアレイに別の配列が含まれている場合は、さらに深く下がっていくことがあります。私はこれが頭部再帰であると信じています。

temp = array[l].slice(); 

ちょっと変わっていますが、これにより、tempという名前の新しい変数に配列を抽出することができます。

temp.unshift(1); 
temp.unshift(l); 
[].splice.apply(array, temp); 

これも書き込み物事の非常にjanky方法であるが、基本的には、一時配列の要素への最初のように1とLを入れ、それをパラメータとして温度と、アレイ上のスプライスを呼び出します。 tempの最初の2つの要素だけがパラメータとして渡されます(2秒前に配置した2つの要素)ので、基本的にはサブ配列を削除し、それを平坦化されたバージョンに置き換えます。

+0

いいえ、配列の長さは3から始まり、ループの各反復は、それをデクリメントします。 [] .spliceは単独では何もしません。あなたはapplyメソッドを読み上げなければなりません。それは非常に奇妙な構文ですが、私はそれを説明する最良の方法は不明です。 – master565

+0

私の謝罪。はい、その2要素配列です。私はそれを誤解しています。 – master565

+0

また、apply関数にも関連しています。スプライスは配列で動作するメソッドなので、[]はその関数を呼び出す空の配列です。 – master565

0

参考文献:splice()apply()unshift()

は、詳細な説明のためのコメントを参照してください。

function flatten(array) { 

    // put the length of the array in l 
    // and create a temp variable with nothing in it 
    var l = array.length, temp; 

    // while(l--) will iterate through 
    // each item in the array backwards 
    // this is just a little faster than doing 
    // for(var i=0; i<array.length; i++) 
    while (l--) { 

     // The current item in the while loop is array[l] 
     // (that's an L, by the way, not a one) 
     // so this is saying "if current item is an array...." 
     if (Array.isArray(array[l])) { 

      // we call the function again (recursion) 
      // if this is an array. eventually, one of 
      // the inner items will be something other 
      // than an array and the recursion will stop 
      flatten(array[l]); 

      // when you call slice() with no parameters 
      // all it does is create a copy of the entire array 
      // and then we store it in temp 
      temp = array[l].slice(); 

      // adds the number 1 to the begining of the array 
      // after we unshift one more time below, 
      // this will become the second parameter for the 
      // splice() call below, which is the number of 
      // items to delete 
      temp.unshift(1); 

      // adds the current index to the begining of the array 
      // this will be the first argument passed to splice() 
      // below, the first argument for splice is the 
      // index to start splicing.. 
      temp.unshift(l); 

      // apply()'s first argument is context, in this case 
      // passing "array" as the context means the action will 
      // be performed on the array variable, 
      // which is the original arrray.. 
      // apply()'s second argumetn is an array, each item 
      // of the array is passed in order to the function 
      // as arguments 
      // So basically this is saying.. "remove the current 
      // index (which is an array) and replace it with each 
      // of the items that were in that array 
      [].splice.apply(array, temp); 
     } 
    } 
} 
+0

覚えておいて、私たちは最初の反復でそれを繰り返すでしょう。3 –

+0

笑、私の間違いだよ、そうだよ、配列には2つのアイテムがあり、それぞれ前に最初の反復では、最初に述べたように、実際には1になります。 –

+0

'while()'を使うと、減算はループの前に起こります。最初の反復では1になります。 –

関連する問題