1

我有一个数字数组,我想获得小于特定 x 的第一个数字,然后是大于相同 x 的第一个数字。

var str = 'some random string that is kind of long',
        items = [],
        position = 10, //varies
        itemsBefore,
        itemsAfter,
        firstItemBeforePosition,
        firstItemAfterPosition; //varies

for(var i = 0, length= str.length; i < length; i++){
    if(str[i] === ' '){
        items.push(i);
    }
}

itemsBefore = items.filter(function(item){
    return item < position;
});

itemsAfter = items.filter(function(item){
    return item > position;
});

firstItemBeforePosition = itemsBefore.length > 0 ? itemsBefore[itemsBefore.length - 1] : 0;
firstItemAfterPosition = itemsAfter.length > 0 ? itemsAfter[0] : str.length;

根据我提供的 JavaScript 代码,items 数组将是[4, 11, 18, 23, 26, 31, 34]firstItemBeforePosition是 4 和firstItemAfterPosition是 11。

有一个更好的方法吗?

谢谢你。

4

2 回答 2

2

这是另一种方法,它需要更少的代码并且不会循环整个列表。它还使用了更少的变量并使用了更多的本机代码函数(应该更快)。

var str, array, length, firstItemBeforePosition, firstItemAfterPosition;

str = 'some random string that is kind of long';
length = 0;
position = 10;

array = str.split(' ');
array = array.map( function( s, i ){ length += s.length; return length+i })

array.some(function(e){
  if ( e < position ) firstItemBeforePosition = e;
  if ( e > position ) {
    firstItemAfterPosition = e;
  }
  return firstItemAfterPosition;
});

some 函数从 1.6 (ES5) 开始在 Javascript 中使用,并且可以在 IE9+ 中使用。与 for 循环或 forEach 不同,some 方法在回调函数返回真值时立即返回。因为firstItemAfterPosition当我们开始时它是空的,所以它是假的,有些会继续下去,直到我们给它分配一个值,到什么时候它才会是真的,有些会退出。

如果位置值列表真的很长,我建议查看二进制搜索,因为它将是 O(log n) 而不是 O(n)。如果您不知道这意味着您的问题大小可能足够小,您不必担心:)

于 2013-11-13T09:02:34.307 回答
1

一个简单的循环应该这样做:

for(var k = 0; k < items.length; k++)
{
  if (items[k] > position)
  {
    firstItemAfterPosition = items[k];
    firstItemBeforePosition = items[k-1];
    break;
  }
}

http://jsfiddle.net/7CZvf/1/

于 2013-11-13T09:03:07.797 回答