给定索引,从数组返回一系列值

时间:2010-06-23 15:50:15

标签: javascript arrays range

首先,道歉,这个应该很简单,但我已经喝了太多咖啡而无法将疲惫的大脑包裹起来(至少没有让它变得比我知道它应该更复杂) )。

假设我有一个简单的Javascript数组,其中包含许多项目:

var items = ["Hello", "This", "is", "an", "array", "with", 
             "a", "number", "of", "items", "in", "it"];

无论出于何种原因,我突然对第二个值感兴趣:

items[1]
//-> "This"

但我也希望得到之前的值,以及接下来的两个值......

//-> "Hello", "This", "is", "an"

这样说:

function getBatch(items, start) {
  // What goes here so it would return the results below?
}

getBatch(items, 0);
//-> ["it", "Hello", "This", "is"]

getBatch(items, 4);
//-> ["an", "array", "with", "a"]

getBatch(items, (items.length-1));
//-> ["in" "it", "Hello", "This"]

为了返回这些结果集,函数getBatch(上面)的代码是什么?

请不要依赖于JQuery的答案:)

2 个答案:

答案 0 :(得分:3)

嗯,显然,天真的第一步就是简单地写

return items.slice(start - 1, start + 2)

但是,这不适用于您需要的包装。一种应该起作用的方法是辅助函数,它有效地使数组在两个边上都是圆形的:

function getElementAtIndex(items, idx) {
    // Normalise the index to an element in the actual range
    while (idx > items.length - 1)
    {
        idx -= items.length;
    }
    while (idx < 0)
    {
        idx += items.length;
    }

    return items[idx];
}

然后你可以简单地手动返回索引周围的四个元素,如下所示:

function getBatch(items, start) {
   return [ getElementAtIndex(items, start - 1),
            getElementAtIndex(items, start),
            getElementAtIndex(items, start + 1),
            getElementAtIndex(items, start + 2)];
}

此方法显示正常here

这可能不是最有效或最优雅的方法,但理解和实现起来相当简单,因此如果此代码不在性能热点中,它最终可能是最实用的。

答案 1 :(得分:1)

已编辑:(已删除原始版本,因为它比此更多垃圾)

function getBatch(items, start) {
  var tmpArr = items;
  tmpArr.splice(0,0,items);

  var offset = (start > items.length-3) ? 0 : items.length;

  return tmpArr.slice(start+offset-1,start+offset+3);
}

编辑2.1(bugfixed)

编辑2.2(移动开始到实际开始并消除一个包裹案例(最终)

好吧,哭泣的男孩被他的母亲照顾。现在,让我们这样做。

function getBatch(items, start) {
  // Behaviour not defined by example
  if(items.length < 4)
    return items;

  // Set start to actual start (start-1), and
  // ensure that start is always within 0 - items.length
  start = ((start-1)+items.length) % items.length;

  // First take care of the easy case.
  if(start < items.length-3) return items.slice(start,start+4);

  // Last x elements + (4-x) elements from beginning of array
  return items.slice(start).concat(items.slice(0,4-(items.length-start)));
}