プロJavascripterの、弓削田です。
先日、とあるプログラムを書いていた時に、配列内にある値が何個含まれているかを確認したいという場面がありました。
ドンピシャの機能は備わっていないようだったので、自作するしか無いということで、
何パターンかのスニペットを作り置きしておきたいと思います。
配列内に任意の値があるかどうかの確認
これは、基本機能で対応可能です。
// 5の値が含まれているかどうかの確認方法
let arr = [0,1,2,3,4,5,6,7,8,9];
if(arr.indexOf(5) !== -1){
console.log("含まれている");
}
else{
console.log("含まれていない");
}
indexOfは、配列内の何番目に値があるか、配列じゃなくて文字列であれば、何文字目に文字が含まれているか、値を取得するプロパティですが、
含まれていない場合は-1が返ってくるという、なんとも特殊な機能です。
でも、値の有り無し判定はこれで簡単にできるんですが、値が複数ある時に、何個含まれているかという機能が無いので、必要な場合に困ります。
配列内に含まれる任意の値の数を取得
とりあえず、配列内に指定した任意の値が何個含まれているかを返す関数を作ってみます。
// 配列内に4の値が含まれている個数を返す
let arr = [0,0,1,1,1,2,2,3,3,3,3,4,4,4,4,4,5,5,5,5,5,55,5,6];
function count_array_in_value(arr,val){
if(!arr
|| typeof arr !== "object"
|| typeof arr.length === "undefined"
|| typeof val === "undefined"){return null;}
let cnt = 0;
for(let i=0; i<arr.length; i++){
if(arr[i] === val){
cnt++;
}
}
return cnt;
}
console.log(count_array_in_value(arr,4));
> 5
ベタな書き方ですが、悪くないでしょう。
もっと簡潔に掛けそうですが、見た目分かりやすいようにしておきました。
そして、関数の精度を上げるために、送り値の判定で配列を送っていない場合や、確認する任意の値が含まれていない場合には、nullを返すようにしておきました。
配列全体での値のユニーク化とそれぞれの値の重複回数を取得
次に、これを発展させて、配列内のユニーク処理をしてみたい思います。
ユニーク処理とは、unixコマンドの"uniq"コマンドのような処理で、このコマンドは、複数行の改行テキストに実行すると、
連なっている同じ値の行を1つにマージしてくれるコマンドです。
[test.txt] : """
aaa
bbb
bbb
ccc
"""
$ uniq test.txt
result : """
aaa
bbb
ccc
"""
こんな感じになります。
このコマンドは処理スピードも早く、sortと組み合わせると「データ解析処理」などにも使えるので、覚えておくと便利でしょう。
ちなみに、-cオプションを付けると、重複する数を結果に表示してくれるようになります。
[test.txt] : """
aaa
bbb
bbb
ccc
"""
$ uniq test.txt
result : """
1 aaa
2 bbb
1 ccc
"""
awkコマンドやgrepコマンドを使うと、テキスト内にある値の計測などができるというワケです。
これをjavascriptでやろうとする時のスニペットは次のとおりです。
let arr = [0,0,1,1,1,2,2,3,3,3,3,4,4,4,4,4,5,5,5,5,5,55,5,6];
function array_uniq(arr){
if(!arr
|| typeof arr !== "object"
|| typeof arr.length === "undefined"){return null;}
let datas = {};
for(let i=0; i<arr.length; i++){
if(typeof datas[arr[i]] !== "undefined"){
datas[arr[i]]++;
}
else{
datas[arr[i]]=1;
}
}
return datas;
}
console.log(array_uniq(arr));
> 0: 2
> 1: 3
> 2: 2
> 3: 4
> 4: 5
> 5: 6
> 6: 1
> 55: 1
返り値に連想配列で対応してみました。
keyに配列の値を入れて、valueに、登場回数を表示しています。
配列の値の配置情報も取得したい
ここまできたら、こんな贅沢にも対応してみましょう。
let arr = [0,0,1,1,1,2,2,3,3,3,3,4,4,4,4,4,5,5,5,5,5,55,5,6];
function array_uniq(arr){
if(!arr
|| typeof arr !== "object"
|| typeof arr.length === "undefined"){return null;}
let datas = {};
for(let i=0; i<arr.length; i++){
if(typeof datas[arr[i]] !== "undefined"){
datas[arr[i]].count++;
datas[arr[i]].position.push(i);
}
else{
datas[arr[i]]={
count:1,
position : [i]
};
}
}
return datas;
}
console.log(JSON.stringify(array_uniq(arr),null " "));
> {
> "0":{"count":2,"position":[0,1]},
> "1":{"count":3,"position":[2,3,4]},
> "2":{"count":2,"position":[5,6]},
> "3":{"count":4,"position":[7,8,9,10]},
> "4":{"count":5,"position":[11,12,13,14,15]},
> "5":{"count":6,"position":[16,17,18,19,20,22]},
> "6":{"count":1,"position":[23]},
> "55":{"count":1,"position":[21]}
> }
それぞれの値のcount値(登場個数)と、position(配置情報)を配列で持たせてみました。
デフォルトプロパティに仕込んで、配列から直接値を取得するようにもできますが、今回はこんな感じで留めておきたいと思います。
アンケート結果などを調べる時に、使えるかもですね。
0 件のコメント:
コメントを投稿