プログラミング言語や環境設定を中心としたパソコン関連の技術メモです。
主にシステム開発中に調べたことをメモしています。TIPS的な位置付けで、気が向いたときにちまちま更新していきます。
JavaScript、配列の要素数を取得する方法について考えてみる
結論から書けば「どれが正解か判断できねっ\(--)/」でした。
誰か正解をご存知でしたらメールで教えてくださいませm(__)m

それでは経緯を書いていきますね。

JavaScriptで配列の要素数を取得する関数を作ろうと思ったのですが、
そんなもんいちいち覚えていないのでgoogle先生で検索しました。

いっぱい出てきました。

配列の要素数は「length」プロパティで取れるよ、という意見がいっぱいありました。
こんな感じのやり方ですねφ(--)

var testArray = ["data1", "data2", "data3"];
alert(testArray.length);

でもですね。
lengthプロパティって奴は、配列の場合「インデックスの最大値+1」を返すんですよね。
ついでに文字列の場合は文字数を返すし。

だからこんなことをやっちゃうとφ(--)

testArray = [];
testArray[5] = 'data';

alert(testArray.length);

「testArray.length」は「6」になっちゃうのです。
「んなアホなことすんなよ」というご意見もごもっともなのですが、
これはちょっと気持ちが悪い。心情的には「1」を返して欲しい。

と言うわけで「lengthプロパティを使うのは微妙だな~」と。
delete演算子を使って配列の要素を削除した状態で呼ばれても悲劇が起こりますしね。
例えばこんなコードを実行するとφ(--)

<script type="text/javascript">

    function count_array(arg1){

        //配列かどうかの判定
        if(!(arg1 instanceof Array)){
            return -1;
        }

        return arg1.length;
    }

    //配列
    var testArray = ["data1", "data2", "data3"];

    //インデックスを詰めないで要素削除
    delete testArray[1];


    alert(count_array(testArray));

</script>

「delete testArray[1];」の有無によらず「count_array()」の戻りが同じ結果になってしまいます。
インデックスが詰まらないのでいずれにせよ「3」になっちゃうのですね。

「値がundefinedな配列の要素がある」と考えれば筋が通っているので、
動きとしては間違っていないと思うのですが、
直感的に「配列の要素数」って感じがしないのですよね。
undefinedな要素はカウントしないべきでしょう。

と言うわけで、lengthプロパティを単純に参照するのは却下(--)ノ

次に見つけたのが「for~in」を使うやり方です。
コードにするとこんな感じφ(--)

<script type="text/javascript">

    function count_array(arg1){
        //配列かどうかの判定
        if(!(arg1 instanceof Array)){
            return -1;
        }

        cnt = 0;
        for(val in arg1){
            cnt++;
        }


        return cnt;
    }

    //配列
    var testArray = ["data1", "data2", "data3"];

    //インデックスを詰めないで要素削除
    delete testArray[1];

    alert(count_array(testArray));

</script>

おぉ、これはなかなか良いんでないかい♪と思ったのですが、
「Array.prototype」を使っちゃうとおかしなことになるのだとか。

確かにこんなコードを書いたらφ(--)

<script type="text/javascript">

    function count_array(arg1){
        //配列かどうかの判定
        if(!(arg1 instanceof Array)){
            return -1;
        }

        cnt = 0;
        for(val in arg1){
            cnt++;
        }

        return cnt;
    }

    Array.prototype.hoge = function(){
        //なんか処理
    }
    Array.prototype.hoge2 = function(){
        //なんか処理
    }


    //配列
    var testArray = ["data1", "data2", "data3"];

    //インデックスを詰めないで要素削除
    delete testArray[1];

    alert(testArray + ":" + count_array(testArray));

</script>

「Array.prototype~」を追加するごとに「count_array()」の戻りの値が増えてっちゃいました。
これじゃー使えないっすね(´・ω・`)

う~ん(-公-;

いろいろ考えた末、最終的にはlengthプロパティをベースに
undefinedな要素を読み飛ばすことにしました。

コードとしてはこんな感じφ(--)

<script type="text/javascript">

    function count_array(arg1){
        //配列かどうかの判定
        if(!(arg1 instanceof Array)){
            return -1;
        }

        //要素数カウント
        cnt = 0;
        for(i = 0; i < arg1.length; i++){
            //undefinedじゃなかったらカウント
            if(typeof arg1[i] !== "undefined"){
                cnt++;
            }
        }

        return cnt;
    }

    Array.prototype.hoge = function(){
        //なんか処理
    }
    Array.prototype.hoge2 = function(){
        //なんか処理
    }

    //配列
    var testArray = ["data1", "data2", "data3"];

    //インデックスを詰めないで要素削除
    delete testArray[1];

    alert(testArray + ":" + count_array(testArray));

</script>

これでほぼ目的の動きは実現できたのですが……。
結局、全要素を回してチェックしちゃっているので、要素数が増えると大変かな~と。
要素数が100,000個の配列とか作って試したら、一秒くらい時間掛かったし。

そんな経緯で「取りあえず作ったけどもっと良い方法があるんじゃないのかなぁ?」と悩んでいます。
jQuery辺りを使って、もっとサクッ!とできないのかな(--?
スポンサーリンク
 
このエントリーをはてなブックマークに追加 

category:● JavaScript  thema:パソコンな日々 - genre:コンピュータ  Posted by ササキマコト 

  関連記事