配列から重複する値を削る関数とin演算子
in演算子の使い方には、こういうのもあるんだなぁというメモ。
実はfor-in文とin演算子をごっちゃに解釈していたのですが、投稿後Twitterでフィードバックをいただき、以下の記事内容を少し修正・加筆しました。
助かります、ありがとうございます!
in演算子
参考:in - MDN
これによると、
オブジェクトにプロパティが存在するかをチェックして、trueかfalseを返すやつで、
var obj = { first: '最初', last: '最後' }; console.log('first' in obj); // true console.log('middle' in obj); // false
値が設定されていようとなかろうと、プロパティがあればtrueになる・・と。
もうひとつ、別物だけれどもついでにメモ。
for-in文
var obj = { first: '最初', last: '最後' }; for(var i in obj){ console.log(i, obj[i]); } // first 最初 // last 最後
みたいに、for-inのセットで使える文法もあったっけ。
これは配列の中身走査にも使えるけど、余分なやつまで引っ掛けたりするので普通は使っちゃいけない。
Array.prototype.po = function() {}; var arr = [1,2,3]; for (var i in arr) { console.log(arr[i]); } // 1, 2, 3, function()...
inって書いてあるけど上述のin演算子とはまったくの別物!
冒頭の重複を削除する関数
これは本題の演算子のほうのinを使った例。
function unique(array) { var storage = {}; var uniqueArray = []; var i,value; for ( i=0; i<array.length; i++) { value = array[i]; if (!(value in storage)) { storage[value] = true; uniqueArray.push(value); } } return uniqueArray; }
使い方
// チェックしたい配列を用意して、 var arr = [1, 2, 3, 1, 3, 3]; // 使うだけ。 arr = unique(arr); // すると配列が、[1, 2, 3]という具合に。
コードの意味
- 引数で渡した配列の要素を、とりあえずプロパティとして仮オブジェクトに格納。
- 最初はもちろん空っぽオブジェクトなので、問答無用で格納。
- 2つ目以降の格納時は、仮オブジェクトに既にプロパティとして格納されてるかをチェック。
- 格納されていない場合は、重複していない=新規の要素として格納。
- 最後に重複を取り除いた配列を返す。
if (!(value in storage))
これがキモですね・・。
単純に「既にプロパティとして存在するかどうか」をT/Fで返してくれるin演算子を、条件分岐に使う・・・!
「配列」の中身を走査するために「オブジェクト」使うっていう発想が!
でも確かにこのやり方賢いな・・。
いやー、奥が深いなぁ。