【问题标题】:In an ordered array of scalars find preceeding smaller and following larger given a number.在标量的有序数组中,给定一个数字,找到前面的较小和后面的较大。
【发布时间】:2013-11-13 08:36:51
【问题描述】:

我有一个数字数组,我想获取小于特定 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。

有没有更好的方法来做到这一点?

谢谢。

【问题讨论】:

  • “有没有更好的方法来做到这一点?”——首先你应该明确实际的问题/任务是什么。它似乎不是关于“数组中的数字”,而是字符串中给定位置之前和之后的第一个空格字符。然后当然有更好的方法来做到这一点 - 假设你不需要实际的数字数组:两个循环,从位置来回移动,直到找到一个空格。
  • 你真的想得到单词的开始和结束位置吗?还是您对从数组中找到第一个更大和更小的数字的问题更感兴趣?
  • 这也是我一直在努力解决的问题 - 如果您想要 itemsBefore 中的最大数字和 itemsAfter 中的最小数字,您可以使用 Math.max 和 Math.max
  • @CBroe 很好地得到空格字符索引会产生一个数字数组,对吧?两个循环。唔。等一下,谢谢,我试试看!
  • 您真的需要那个数字数组(如果需要,为什么?),还是只需要您在显示的代码的最后两行中设置的两个值?

标签: javascript arrays filter


【解决方案1】:

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

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 函数在 Javascript 1.6 (ES5) 中可用,并且可以在 IE9+ 中运行。与 for 循环或 forEach 不同,some 方法在回调函数返回真值时立即返回。由于firstItemAfterPosition 在我们开始时为空,所以它是虚假的,有些会继续运行,直到我们为它分配一个值,直到它是真实的,有些会退出。

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

【讨论】:

    【解决方案2】:

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

    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/

    【讨论】:

      猜你喜欢
      • 2020-07-30
      • 1970-01-01
      • 2012-09-23
      • 2017-09-12
      • 1970-01-01
      • 2015-11-24
      • 2016-06-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多