Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

Array#fill中でArray#fillをやると特定セルだけ更新という事ができない

shuzo-kino.hateblo.jp
上記の記事で紹介したArray#fill中でArray#fillを呼び出す方式だと、特定セルだけ更新という事ができません。
……for文のネストは使ったら負けな気がするので、ここはmathjs使ったほうが良いように感じました。

実際のところ。

まず、単純な2x2の-1で満たされた多次元配列の要素一個を変えるケースを考えます。
何も考えずに力技。意図通りに動きます。

bar = [[-1,-1],[-1,-1]]
//[ [ -1, -1 ], [ -1, -1 ] ]
bar[0][0] = 8
//8
bar
//[ [ 8, -1 ], [ -1, -1 ] ]

個別にArrayから起こしても同じ。

bar = [Array(2).fill(-1),Array(2).fill(-1)]
//[ [ -1, -1 ], [ -1, -1 ] ]
//bar[0][1] = 8
8
> bar
[ [ -1, 8 ], [ -1, -1 ] ]

ところがギッチョン、これを前回の記事でやったようなArray#fill利用の多重挿入にすると……

> bar = Array(2).fill(Array(2).fill(-1))
[ [ -1, -1 ], [ -1, -1 ] ]
> bar[0][1] = 8
8
> bar
[ [ -1, 8 ], [ -1, 8 ] ]

これでは意図通りの挙動になりません。
ちなみにこれ、文字や数値では発生しないケースです。
C言語のポインタみたいに同一のオブジェクトを参照しに行ってるのが原因?

一方、mathjsのsubset関数ならそういった心配はありません。
今度は前回と同様9x16の規模に拡大し1,1の要素を3にしてみます。

math = require('mathjs')
a = math.matrix().resize([9,16],-1)
a.subset(math.index(1,1),3)
/*
Matrix {
  _data: 
   [ [ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
     [ -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
     [ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
     [ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
     [ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
     [ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
     [ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
     [ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ],
     [ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ] ],
  _size: [ 9, 16 ],
  _datatype: undefined }
*/

今度はうまくいきましたね。