2016-03-21 4 views
1

2次元配列からすべての要素をその行で取り出し、1次元配列を返す関数があります。 配列にはさまざまな量の列と行があります。異なる長さの配列を含む2次元配列の行を反復する

例:

let arr = [ 
    [1, 2, 3, 4], 
    [5, 6, 7, 8], 
    [9, 10, 11, 12] 
]; 

戻り値:

[1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12] 

私が思いついた機能:

convertList = (list) => { 
    let result = []; 
    let listTotalEntries = R.sum(R.map(R.length)(list)); 
    let mod = R.modulo(R.__, list.length); 

     let counterRow = -1; 

     for (let i = 0; i < listTotalEntries; i++) { 
      if (mod(i) === 0) { 
       counterRow++; 
      } 
      if (list[mod(i)][counterRow]) { 
       result.push(list[mod(i)][counterRow]); 
       console.log(list[mod(i)][counterRow]); 
      } 
     } 
     console.log(result); 
     return result; 
}; 

質問:この関数は、正方行列でのみ動作します - どのようにすることができます私はそれが含まれている配列の可変長で動作するように?

例:

let arr = [ 
    [1, 2], 
    [], 
    [9, 10, 11, 12] 
]; 

が返す必要があります:あなたの助けを

[1, 9, 2, 10, 11, 12] 

ありがとう!

マフ

答えて

2

あなたはここでramda.jsタグを持っていました。役立つ二つの機能があるのでRAMDAで、それは、非常に単純です:

const convertList = compose(flatten, transpose); 
convertList(arr); //=> [1, 9, 2, 10, 11, 12] 

その主対角の上に行列を反転させtransposeが、それは、列とその逆に行を変更し、です。 flattenは、リストのリストをプレーンなリストに変換します。したがって、このようなcomposelist => flatten(transpose(list))と同等のものを作成します。

これは、Ramda REPLでご覧になれます。

+0

うわー!魅力的で、しなやかで、きちんとしています!ラムダに転位のような機能があることは分かりませんでした - すべての機能と関連する可能性を内在化するには時間と経験が必要です。ありがとう! – Raggamuffin

+0

はい、Ramdaチームは機能の発見方法の改善に取り組んでいます。その一歩は[昨日公開されたばかりだった](https://github.com/ramda/ramda/wiki/What-Function-Should-I-Use%3F)。 –

+0

素晴らしい! *ブックマーク* - マニュアル/ガイドの進歩を楽しみにしています。私はバージョン0.17のものを見つけましたが、序論の章だけがまだ利用可能であるように見えました。私は彼らがドキュメントの適切な補足としてそれを書いていることを願っています。 – Raggamuffin

2

このシンプルなものを試しましたか?

var singleDimensionArr = arr.reduce(function(prev,current){return prev.concat(current)}); 

例えば

[ 
    [1, 2], 
    [], 
    [9, 10, 11, 12] 
].reduce(function(prev,current){return prev.concat(current)}); 

出力[1, 2, 9, 10, 11, 12]

編集:以下OPからの入力に基づいて

、連結は賢明

var max = Math.max.apply(null, arr.map(function (a) { return a.length; })); 
var finalArr = []; for(var i = 0; i < max; i++) 
{ 
    for(var j = 0; j < arr.length; j++) 
    { 
     arr[j][i] ? finalArr.push(arr[j][i]) : ""; 
    } 
} 
console.log(arr); 
列を発生する必要があるので
+0

OPが追加した結果と一致しません – Marie

+0

申し訳ありませんが、9と2のreturn文にタイプミスがあります。 あなたのソリューションは項目を列で選び出します - 行ごとに項目を選択したいと思います。 – Raggamuffin

+0

@Marieオタクがあったので(質問を完全に変えた) – gurvinder372

2

私は、この例では、大きなスパース配列は、配列が正方形であれば、それは属します各項目を入れて作るステップ・バイ・ステップの配列

var arr1 = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], 
 
    arr2 = [[1, 2], [], [9, 10, 11, 12]]; 
 

 
function single(array) { 
 
    var r = [], 
 
     max = Math.max.apply(null, array.map(function (a) { return a.length; })), 
 
     i = 0, j, 
 
     l = array.length; 
 

 
    while (i < max) { 
 
     for (j = 0; j < l ; j++) { 
 
      i in array[j] && r.push(array[j][i]); 
 
     } 
 
     i++; 
 
    } 
 
    return r; 
 
} 
 

 
document.write('<pre>' + JSON.stringify(single(arr1), 0, 4) + '</pre>'); 
 
document.write('<pre>' + JSON.stringify(single(arr2), 0, 4) + '</pre>');

+0

良い1ニーナ:) – gurvinder372

+0

ありがとう - 私はあなたのソリューションをupvotedとチェックしてジェームズ 'それは少しコンパクトなので、削減とフィルタを使用しています。 – Raggamuffin

+0

@Raggamuffinよりコンパクトに見えるかもしれませんが、whileループとforループよりも必ずしも優れたパフォーマンスを示すわけではありません。 –

1

を通過することをお勧め。次に、入力項目が存在しない場合に発生するヌル値をフィルタリングします。

let arr = [ 
 
    [1, 2], 
 
    [], 
 
    [9, 10, 11, 12] 
 
]; 
 

 
var out = arr.reduce(function(o,n,i,a) { 
 
    for (var j=0;j<n.length;j++){ 
 
    o[a.length * j + i] = n[j]; 
 
    } 
 
    return o; 
 
},[]).filter(function(n) { 
 
    return n !== null; 
 
}); 
 

 
alert(JSON.stringify(out));