2011-01-02 10 views
3

私はJavaの配列を持っているとします。インデックスのある配列の次の要素と前の要素を取得します。

0  => 0x0000FF 
1200 => 0x00CCFF 
28800 => 0xFF0AFF 
36000 => 0xFFFFFF 

特定のインデックス値に該当する要素を特定する方法を教えてください。前の例では、値31073がある場合、28800 => 0xFF0AFF36000 => 0xFFFFFFを取得する必要があります。

+0

連想配列ですか? 'myarray ['0'] = 0x0000FF;'? – stef

+0

オブジェクトで簡単でしょうか。配列でははるかに難しい。 –

+0

@Tomcat:配列インデックスに予測可能な順序はありますか? – user113716

答えて

1

両方のおかげで、quixotopatrick dwあなたの詳細なコメントと回答があります。私はしかし、わずかに異なるソリューションを持っています。 1次元配列を使用する初期のアプローチを維持したいと思っていましたが、私が見ることができるより簡単で効率的で、次のように別の次元を追加しました。ここで使用されている配列は予測可能性を示しますが、プロジェクトが完成するとそうなることはありません。

var colors = [ 
    [0,  '121D4A'], 
    [10800, '000000'], 
    [21600, 'FF5900'], 
    [32400, 'D3EEF0'], 
    [43200, '7DCDFF'], 
    [54000, '7DA6FF'], 
    [64800, 'FF5900'], 
    [75600, '31428C'], 
    [86399, '121D4A'], 
]; 

function gradientStop(color1, color2, gradStop){ 
    var r = Math.floor(gradStop * parseInt(color2.substr(0, 2), 16) + (1 - gradStop) * parseInt(color1.substr(0, 2), 16)).toString(16); 
    var g = Math.floor(gradStop * parseInt(color2.substr(2, 2), 16) + (1 - gradStop) * parseInt(color1.substr(2, 2), 16)).toString(16); 
    var b = Math.floor(gradStop * parseInt(color2.substr(4, 2), 16) + (1 - gradStop) * parseInt(color1.substr(4, 2), 16)).toString(16); 
    return (r.length < 2 ? '0' + r : r) + (g.length < 2 ? '0' + g : g) + (b.length < 2 ? '0' + b : b); 
} 

function getColor(colors, currentIndex){ 
    for(var i = 0, m = colors.length; i < m; i++){ 
     if(currentIndex >= colors[i][0]){ 
      if(typeof(colors[i + 1]) !== 'undefined'){ 
       if(currentIndex <= colors[i + 1][0]){ 
        return gradientStop(colors[i][1], colors[i + 1][1], (currentIndex - colors[i][0])/(colors[i + 1][0] - colors[i][0])); 
       } 
      } 
     } 
    } 
} 

また、はいヘムロックそれはProgrammatic gradient stops with Javascriptで私の質問の拡張、したがってgradientStop()機能でした。

+0

+1いいですね。あなたのオリジナルと@ quixotoのソリューションの間のハイブリッドのソート。 – user113716

2

Javascriptの疎な配列でこれを実現する方法はありません。効率を維持しながら任意のスパースインデックスに対してこれを行う最も簡単な方法は、インデックスの別のルックアサイドソート配列をメイン配列に保持することです。次に、ルックアサイドリストを歩いて右隣のインデックスを見つけ、メインアレイに戻り値を取得することができます。

配列が巨大であるか、アクセスがO(アイテム)より高速である必要がある場合は、ルックアサイドオブジェクトのさまざまなツリー構造を調べることができます。

+0

** @ quixoto **;配列自体は巨大ではありません。可能な最大インデックス値は86399ですが、0〜86399のインデックスを持つ値は約10〜20だけです。 – Dan

+0

@TomcatExodusあなたが効率的であるかどうかについては心配する必要はありません。ここで答えを構築するだけです。http://stackoverflow.com/questions/4580105/programmatic-gradient-stops-with-javascript;配列を一度記入してからインデックスを作成してください。 – Hemlock

+1

@TomcatExodus:10-20個の値しかない場合は、それらをループすることはパフォーマンスがあまり良くありません。それらの10〜20の値で別のリストを保管してください。それらのうち最も近いものを見つけて、それらをインデックスとしてメイン配列に戻します。 –

2

ここには、体のないループがいくつかあるwhile()を使用している方法があります。

開始点は常に中間にあるとします。そうでない場合は、2回の追加テストが必要になります。

また、出発点が色のすぐ上にあればどうなるかわからなかったので、私はそれについて説明しませんでした。

例:私はちょうどここにフォローアップしたかったhttp://jsfiddle.net/tcVxP/4/

var num = 31234, 
    curr = num, 
    prev, 
    next; 

while(!colors[--curr] && curr); 
prev = colors[curr]; 

curr = num; 
while(!colors[++curr]); 
next = colors[curr]; 
+0

この手法の注意点:可能なすべてのインデックスを歩き回って隣接する値を見つけるため、そのパフォーマンスは可能な値域全体のサイズにおいて線形です。これを頻繁に呼び出す必要がある場合、または超高速にする必要がある場合は、少し注意してください。また、バグ:テストが 'undefined'の厳密なテストではないので、実際のネイバーインデックスの値がゼロか他の何かが偽であれば、それを見つけることはできません。 –

+1

@quixoto:すべてのインデックスを歩いているのは間違いありませんが、 'while'ステートメントの本文がないので、すばやくすべきです。別のリストを保持することについてのコメントのあなたのアイデアは良いものです。答えに追加する必要があります。バグに関しては、それは本当ですが、私は、質問の配列が正確にインデックス '0'が唯一のfalsey値を持っているという仮定の下で働いています。したがって、最初の 'while'の' && curr'部分で覆われています。残念ながら、私たちは本当にその質問に完全な絵を持っていません。 – user113716

+1

それは*私の答えです - 明らかにそれはできるだけ明確に書かれていません。 :) FWIWは、ループ中にどのくらい仕事をしているかにかかわらず、すべてのインデックスを歩くことはO(n)ですが、詳細がなければ、最適化する価値があるかどうかを知ることは困難です。 –

関連する問題