for(var i in Array)
時々勘違いしてハマる
var array = ['a', 'b', 'c'];
for(var i in array){
console.log(typeof i, i);
}
string 0
string 1
string 2
俺がハマった例として、オセロの盤面を扱った時など
// オセロの盤面
var board = [];
for(var i = 0; i < 8; i++){
board[i] = [];
for(var j = 0; j < 8; j++){
// ぜんぶ0
board[i][j] = 0;
}
}
// 28番目だけ1
board[4][3] = 1;
// 1であるマスが何番目か調べる
for(var i in board){
for(var j in board[i]){
// 期待する答えは28だが…
if(board[i][j] == 1) console.log(i+j*8);
}
}
424
i == 4, j == 3なので「4+3*8」になるはずが、
inで取り出した要素名はArrayであろうと文字列と化すので「"4"+"3"*8」となり「+」が文字列の連結扱いされて
「"4"+"3"*8」→「"4"+24」→「"424"」になっちゃいます
inで取り出した数値は、Number()などで変換してから使うと解決
Array.forEach()
@opengl-8080 さんからいただいたコメントや、ちょこっと調べたところによると、
for(var i in array) で出てくるキーは、自分やフレームワークが追加したプロパティやメソッドも含まれるので、
配列としての走査には推奨されないようです。
モダンブラウザであれば、 Array.forEach() メソッドを使うとよいようです。
↓でforEach使ってみましたが、ちょっとスッキリしない書き方になりました。。。
// オセロの盤面
var board = [];
for(var i = 0; i < 8; i++){
board[i] = [];
for(var j = 0; j < 8; j++){
// ぜんぶ0
board[i][j] = 0;
}
}
// 28番目だけ1
board[4][3] = 1;
// 1であるマスが何番目か調べる
board.forEach(function(iVal, i){
iVal.forEach(function(jVal, j){
if(board[i][j] == 1) console.log(i+j*8);
})
});
28
for(var i of Array.keys())
@hikaru_oao さんからいただいたコメントによると、for-of という構文もあるそうです。
ただ、MDNによると、安定してないとか変更の可能性があるとか、おどかしてきてるので、近い未来までのブラウザ互換性を期待するような商品に組み込むなどは避けた方がいいのかもしれません。
// オセロの盤面
var board = [];
for(var i = 0; i < 8; i++){
board[i] = [];
for(var j = 0; j < 8; j++){
// ぜんぶ0
board[i][j] = 0;
}
}
// 28番目だけ1
board[4][3] = 1;
// 1であるマスが何番目か調べる
for (var i of board.keys()) {
for (var j of board[i].keys()) {
if (board[i][j] == 1) console.log(i+j*8);
}
}
28
「of Array」にすると値を走査できるようです。
これはたいへんスッキリ書けますね!