【问题标题】:Get the next and previous element of an array given an index获取给定索引的数组的下一个和上一个元素
【发布时间】:2011-01-02 20:58:58
【问题描述】:

鉴于我在 Javascript 中有一个数组,其值是这样的;

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

如何确定给定索引值位于哪些元素之间?对于前面的例子,如果我有值 31073,我需要检索 28800 => 0xFF0AFF36000 => 0xFFFFFF

【问题讨论】:

  • 你的意思是关联数组? myarray['0'] = 0x0000FF; ?
  • 有一个对象会很容易。使用数组要困难得多。
  • @Tomcat:数组索引有可预测的顺序吗?
  • @stef;不,数字索引。 @Felix 克林;我正在考虑,我将如何去实现它?
  • @Felix:如果没有保证属性的顺序,如何使用对象来完成?

标签: javascript arrays


【解决方案1】:

没有“内置”方法可以使用 Javascript 的稀疏数组来完成此任务。在保持一定效率的同时对任意稀疏索引执行此操作的最简单方法是将索引的另一个后备排序数组保留到主数组中。然后您可以遍历后备列表以找到正确的邻居索引,然后返回主数组以获取它们的值。

如果您的数组很大或访问需要比 O(items) 更快,您可以查看后备对象的各种树结构。

【讨论】:

  • @quixoto;数组本身不会很大。最大可能的索引值为 86399,但是索引在 0 到 86399 之间的值只有大约 10 到 20 个。
  • @TomcatExodus 如果您只是在stackoverflow.com/questions/4580105/… 的答案上构建,您不必担心效率;只需填写一次数组,然后从那时起对其进行索引。
  • @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];

【讨论】:

  • 关于此技术的注意事项:它的性能在整个可能的值范围的大小上是线性的,因为它遍历每个可能的索引以找到具有值的相邻索引。如果您需要经常调用它或需要它超快,请小心一点。还有一个错误:因为该测试不是对undefined 的严格测试,如果真实邻居索引处的值为零或其他错误,您将找不到它。
  • @quixoto:遍历每个索引是对的,尽管它应该很快,因为while 语句没有正文。您在评论中关于保留单独列表的想法是一个很好的想法。您应该将其添加到您的答案中。关于这个错误,这是真的,除了我在假设问题中的数组在索引0 中是准确的具有唯一错误值的情况下工作。因此,它被第一个while&& curr 部分覆盖。不幸的是,我们并没有真正了解问题的全貌。
  • 我的答案——显然它没有写得清楚。 :) FWIW,不管你在循环中做了多少工作,遍历每个索引都是 O(n),但同意如果没有更多细节,很难知道什么值得优化。
  • @quixoto:抱歉,我只是快速浏览了一下,一定是对评论更加关注了。为您的解决方案 +1。
【解决方案3】:

我只是想在这里跟进;

感谢 quixotopatrick dw 提供详细的 cmets 和答案。但是,我采用了稍微不同的解决方案。虽然我想保持使用一维数组的初始方法,但从我所见,添加另一个维度更容易和有效,如下所示。此处使用的数组确实表现出可预测性,但一旦项目完成,情况可能并非如此。

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() 函数。

【讨论】:

  • +1 看起来不错。您的原始解决方案和@quixoto 的解决方案之间的某种混合体。
猜你喜欢
  • 1970-01-01
  • 2021-11-24
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-18
相关资源
最近更新 更多