2011-01-02 4 views
3

Учитывая, что у меня есть массив в Javascript со значениями как таковыми;Получить следующий и предыдущий элемент массива с индексом

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

Как определить, какие элементы имеют значение индекса? В предыдущем примере, если у меня есть значение 31073, мне нужно получить 28800 => 0xFF0AFF и 36000 => 0xFFFFFF

+0

Вы имеете в виду ассоциативный массив? 'myarray ['0'] = 0x0000FF;'? – stef

+0

Было бы легко с объектом. Намного сложнее с массивом. –

+0

@Tomcat: Существует ли предсказуемый порядок индексов массива? – user113716

ответ

1

Я просто хотел следовать здесь;

Благодаря как quixoto и PATRICK Dw для ваших подробных комментариев и ответов. Я, однако, пошел с немного другим решением. Хотя я хотел сохранить свой первоначальный подход к использованию одномерного массива, это намного проще и эффективнее, чем я могу видеть, чтобы добавить другое измерение, как показано ниже. Используемый здесь массив демонстрирует предсказуемость, но это может быть не так, как только проект будет завершен.

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])); 
       } 
      } 
     } 
    } 
} 

А также; Да Hemlock Это было расширение по моему вопросу на Programmatic gradient stops with Javascript, следовательно функция gradientStop().

+0

+1 Это хорошо выглядит. Тип гибрида между вашим оригиналом и решением @ quixoto. – user113716

2

Невозможно «встроенного» способа выполнить это с разреженными массивами Javascript. Самый простой способ сделать это для произвольных разреженных индексов, сохраняя при этом некоторую эффективность, - это сохранить другой отсортированный массив индексов в основном массиве. Затем вы можете просмотреть список lookaside, чтобы найти индексы правого соседа, и вернуться к основному массиву, чтобы получить их значения.

Если ваш массив будет огромным или доступ должен быть быстрее, чем O (элементы), вы можете посмотреть на различные древовидные структуры для объекта lookaside.

+0

** @ quixoto **; Массив не будет огромным как таковым. Максимально возможное индексированное значение составляет 86399, но будет только от 10 до 20 значений с индексами от 0 до 86399. – Dan

+0

@TomcatExodus Вам не нужно беспокоиться об эффективности, если вы просто строите ответ на этот вопрос http://stackoverflow.com/questions/4580105/programmatic-gradient-stops-with-javascript; Просто заполните массив один раз, а затем проиндексируйте его с этого момента. – Hemlock

+1

@TomcatExodus: Если всего 10-20 значений в целом, то прохождение через них тривиальной производительности. Сохраните отдельный список с такими значениями 10-20. Найдите ближайших из них, а затем используйте их как индексы обратно в основной массив. –

2

Вот один из способов, который просто использует пару while() петель без тела.

Предполагается, что отправная точка всегда будет находиться между ними. Вам понадобится несколько дополнительных дополнительных тестов, если это не так.

Кроме того, я не был уверен, что произойдет, если начальная точка находится прямо на цвет, поэтому я не учитывал это.

Пример: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' имеет единственное значение false. Таким образом, он покрывается частью '&& curr' первого' while'. К сожалению, у нас действительно нет полной картины в вопросе. – user113716

+1

Это * мой ответ - видимо, это не так ясно написано, как могло бы быть. :) FWIW, ходя по каждому индексу O (n), независимо от того, сколько работы вы делаете во время цикла, но согласитесь, что без подробностей трудно понять, для чего стоит оптимизировать. –