78017


この場合、rowsに対して期待された結果[[right, black], [right, red]]が得られていないようです。誰か問題点を指摘できますか ?

[code]

    const values = [[,,],[,'right','black'],[,'right','red'], [,'left','black'],[,'left', 'black']];
    const cols=[];
    const rows=[];
    for(let row=1;row<5;row=row+1){
      if(values[row][1]=='right'){
        cols.splice(0);
        for(let i=1;i<3;i=i+1){cols.push(values[row][i]);}
        rows.push(cols);
      }
    }
    Logger.log(rows)// [[right, red], [right, red]]
    
[/code]


CC BY-SA 4.0
2021-07-07T05:52:32.487
78016
2021-07-07T06:19:06.347
47188
question
google-apps-script
特定要素が存在する配列のみ別の配列に追加する


## 問題点

`rows` に constで宣言した配列`cols`をpushしているのがミステイクです。  
配列Aに配列Bをpushする場合、実際に配列Aにpushされるデータは配列Bの参照です。  
なので、質問文のコードのrowsに入っているデータは`[cols, cols]`と同義です。  
試しに、質問文のコードに続いて以下のコードを実行してみてください。

[code]

    cols.push('foo');
    Logger.log(rows)
    
[/code]

結果は、`[[right, red, foo], [right, red, foo]]` になるはずです。  
このことで、rowsの中に入っているのはcolsの参照でしかないことが分かります。

この現象を回避するには、rowsにpushする配列colsをif文のスコープ中で毎回新しく作成すれば良いです。

[code]

    const values = [[,,],[,'right','black'],[,'right','red'], [,'left','black'],[,'left', 'black']];
    // const cols は不要。
    const rows=[];
    for(let row=1;row<5;row=row+1){
      if(values[row][1]=='right'){
        let cols = []; // if内でブロックスコープとしてcolsを定義する。
        for(let i=1;i<3;i=i+1){cols.push(values[row][i]);}
        rows.push(cols);
      }
    };
    Logger.log(rows) // [ [ 'right', 'black' ], [ 'right', 'red' ] ]
    
[/code]


CC BY-SA 4.0
2021-07-07T06:19:06.347
78017
2021-07-07T06:19:06.347
46944
78016
answer