2017-08-15 4 views
0

コンテキストパラメータを使用せずに、指定された配列の内容全体を素早く `Array.prototype`メソッド変数に渡す簡単な方法はありますか?

私はキャンバスのスペースをユーザーがクリックすると、座標を追跡するために、アレイdocketを作成しました。メインプログラムループ中、選択されたピクセルを見ることができるように、配列は描画関数によって走査される。もともと、イベントリスナーの中で、私はpush()メソッドを使用していましたが、ピクセルを切り替える方法を欲しがっていました。

コード記述

以下わかるように、私は私のローカル配列param.arrayに全体docketアレイを押してトリガがローカル変数param.entryに配位割り当てることを可能にする、Array.prototypeする方法poke()を添加。 entryarrayにプッシュされ、arrayはメインのpoke()ループによって処理され、重複する値がないことが保証されます。一致が見つかった場合は、両方の要素が消滅し、param.arrayが先頭に返され、最終的にはdocketが1だけ縮小されます。一致が見つからない場合は、何の要素が全滅されていないとparam.arrayは、最終的にdocket

1による主な問題拡大し、トップに返されます。例1

とにかく、この方法は、現在書かれているように、それがなければならないがしたがって、以下のように呼び出すことができます。

docket.poke(docket, e.key);注:わかりやすくするために、私はキーボードのキー値を使用しています。

Array.prototype.poke = function(a, b) { 
    var bool = { }, i = { }, param = { }; 
    param.array = a; param.entry = b;  
    // 
    param.array.push(param.entry); 
    i.len = param.array.length; 
    i.end = i.len - 1; 
    // 
    for (i.cur = 0; i.cur < i.len; i.cur++) { 
    bool.match = param.array[ i.cur ] == param.array[ i.end ]; 
    bool.nSelf = !(i.cur == i.end); 
    // 
    if (bool.match && bool.nSelf) { 
     param.array.splice(i.end, 1); 
     param.array.splice(i.cur, 1); 
     // 
     i.end -= 2; 
     i.len -= 2; 
    } 
    } 
    // 
    return param.array; 
} 

これは少し冗長なようですが、2つの重要な利点があります。最初は読みやすさと美しさ。視覚的にはdocketの内容をローカル配列に渡して処理し、その結果を目に見える形でトップに戻すことができれば非常に理解しやすくなります。次に、この例と次の例では、重複した値の検出時に誤検出を除外するために、一種の紛らわしい真理テストを使用しています。この例にはあまりありません。 param.arrayの各要素とparam.entryの各要素をタイトでナンセンス・フォー・ループで比較すると、簡単に書き直すことができます。

主な問題:例2

docket.poke(e.key);

少ない冗長より望ましいアプローチです。これは私のコードです。

Array.prototype.poke = function(a) { 
    var bool = { }, entry = a, i = { }; 
    // 
    this.push(entry); 
    i.len = this.length; 
    i.end = i.len - 1; 
    // 
    for (i.cur = 0; i.cur < i.len; i.cur++) { 
    bool.match = this[ i.cur ] == this[ i.end ]; 
    bool.nSelf = !(i.cur == i.end); 
    // 
    if (bool.match && bool.nSelf) { 
     this.splice(i.end, 1); 
     this.splice(i.cur, 1); 
     // 
     i.end -= 2; 
     i.len -= 2; 
    } 
    } 
} 

あなたが見ることができるように、これはコールの冗長性を排除し、それは私が上記の単純な比較を使用してコードまで本当にスリムにする方法のいくつかの読みやすさと、より重要な機会を生け贄に捧げます。

私は、私が配列の完全な内容をローカル変数に渡すことを可能にする、私が見逃してしまった明白でない方法があるかどうか疑問に思っています。独自の方法。

アイデア?

+1

なぜ、これらすべてのローカルオブジェクト?あなたはプリミティブに対して何かを持っていますか? – trincot

+0

私はそれが整理されたままにするのに役立つと思います。私はブールオブジェクトを例として引用します。私はあなたがforループ条件領域をチェックアウトすると、変数に付いた単語boolを見ることができます。それは、私の心の中で何が起こっているのかをもっと簡単に見られるようにします。私は学んでいるし、私のプラクティスは絶えず変化しています。 – Musixauce3000

+1

"自分のメソッドのパラメータとして渡すことなく、配列の内容にアクセスする" - これは 'ちょうどあなたが今説明したものです。それがなぜ「可読性を低下させる」と思うのかはわかりません。 'this'は' 'メソッドとしてこの関数を呼び出すときに使われるオブジェクト ''を意味します。これは読みやすさの点ではまさにあなたがやりたいことです。私はまた、 'i'と' bool'変数を不必要にあなたのローカル変数に「名前空間」することは、かなり混乱し、コードの読みやすさに害を及ぼしているという考え方をもう一度示します。 – apsillers

答えて

2

配列を引数として渡す場合、プロトタイプにメソッドを定義する理由はありません。プレーンな関数はそれでうまくいくでしょう。

コードの2番目のバージョンは、配列を関数に渡すのではなく、指定された配列にメソッドを適用できるという利点があります。

場合のコードは、しかし、簡単にすることができます。

  • あなたが唯一のあなたはまだ
  • あなたが使用する配列に発生していない判断した後要素を追加しますindexOf

Array.prototype.toggle = function(value) { 
 
    var index = this.indexOf(value); 
 
    if (index > -1) { 
 
     this.splice(index, 1); 
 
    } else { 
 
     this.push(value); 
 
    } 
 
} 
 

 
var a = [4,2,5,8]; 
 
a.toggle(2); 
 
console.log(a.join()); 
 
a.toggle(2); 
 
console.log(a.join());

NB:私は個人的にはtoggleという言葉がpokeより多く見つかっています。

Setの力を考えてみましょう:一定の時間内に(配列の実装には線形時間が必要ですが)既存のメンバーが見つかり、一定時間内にそれを削除することもできます。だから、あなたがこれ以外の何かを使用することにオープンしているなら、Setに行ってください。

Set.prototype.toggle = function(value) { 
 
    if (!this.delete(value)) this.add(value); 
 
} 
 

 
var a = new Set([4,2,5,8]); 
 
a.toggle(2); 
 
console.log([...a].join()); 
 
a.toggle(2); 
 
console.log([...a].join());

+0

これは素晴らしいです。私は仕事を辞めて、それがどのようになったのかを教えてもらうために、このうちのいくつかを試してみます。 – Musixauce3000

+0

まだ 'Set'をテストしていません。セットの大きさにかかわらず、ルーチンが同じ量の時間を取ると言いますか?ニート!とにかく、私はあなたが提案した 'indexOf()'に行きました。また、 'apsillers 'のように' this'という配列をインポートしました。ここに私の新しいコードがあります。 'Array.prototype.poke = function(a){ \t var array = this、value = a; \t var bool = {}、i = {}; \t i.match = array.indexOf(value); \t bool.match = i.match> = 0; (bool.match){ \t \t array.splice(i。マッチ、1); \t \t戻り配列。 \t} \t else { \t \t array.push(value); \t \t戻り配列。 \t} } '。ありがとう! – Musixauce3000

+0

ようこそ。実際、Setは一定時間 'has'、' get'、 'set'メソッドを提供します。注意:なぜ、 'value'に' a'を代入するのではなく、 'value'パラメータをすぐに呼び出さないのですか?また、 'return array;'は2回発生する必要はなく、 'if ... else'ブロックの後に置くだけです。 – trincot

関連する問題