从数组(切片)中提取x项,但如果到达则从头开始继续

时间:2021-05-31 21:34:43

Lets say I have:

让我们说:

var array = [0,1,2,3,4,5,6,7,8,9]

I define:

var itemsToExtract  = 5
var startindex = 7
var direction = "forward"

I want to be able to do:

我希望能够做到:

array.someMethod(startindex, itemsToExtract, direction)

and get

[7,8,9,0,1]

I also want it to work backwards, if I set direction to "backward" (slicing from right to left).

如果我将方向设置为“向后”(从右到左切片),我也希望它向后工作。

I wasnt too lazy and tried something already, see here: http://jsfiddle.net/MkNrr/

我不是太懒了,已经尝试了一些东西,请看这里:http://jsfiddle.net/MkNrr/

I am looking for something "tidier" if there is, also is there a name for this method, is it a known problem?

我正在寻找“更整洁”的东西,如果有的话,这个方法也有名称,这是一个已知的问题吗?

Background: I am trying to build a sequential pre image loader (load one image(src) after the other) for use in an image gallery. Maybe even such a libary already exists?

背景:我正在尝试构建一个顺序的预图像加载器(在另一个之后加载一个图像(src))以在图库中使用。也许甚至这样的图书馆已经存在?

6 个解决方案

#1


1  

How about a function that returns the forward and back arrays? That way you don't need a switch. Something like this:

返回前向和后向数组的函数怎么样?这样你就不需要开关了。像这样的东西:

function overslice(arr, idx, items) {

  var fwd = arr.filter(function(v,i){ return i >= idx }).slice(0, items),
      back = arr.filter(function(v,i){ return i <= idx }).slice(-items);

  while (fwd.length < items) {
    fwd = fwd.concat(arr).slice(0, items);
  }

  while (back.length < items) {
    back = arr.concat(back).slice(-items);
  }

  return { fwd: fwd, back: back };
}

Then you can use it like:

然后你就可以使用它:

var array = [0,1,2,3,4,5,6,7,8,9]
var result = overslice(array, 7, 5);

console.log(result.fwd, result.back); //=> [7, 8, 9, 0, 1] [3, 4, 5, 6, 7] 

#2


1  

My approach:

function overslice(array, startindex, count, direction) {
    var retarray = [];
    var increment = (direction === 'backward') ? -1 : 1;

    for(var c=0, i = startindex; c<count; i+=increment, c++){
        retarray.push(array[(i + array.length)%array.length]);
    }
    return retarray;
}

Working fiddle

UPDATE

Another version using the count variable to dictate the direction using positive/negative values and with a fix to allow use of count larger than the array length:

另一个版本使用count变量来指示使用正/负值的方向,并使用修复来允许使用大于数组长度的计数:

function overslice(array, startindex, count) {
    var retarray = [];
    var increment = (count >= 0) ? 1 : -1;
    count = Math.abs(count);
    for(var i = startindex, c = 0;c<count;i+=increment, c++){
        if(i<0) i= array.length-1;  
        retarray.push(array[i%array.length]);
    }
    return retarray;
}

Demo fiddle

#3


0  

Its not much, but looks fine JS Bin:

它不多,但看起来很好JS斌:

function overSlice(arr, start, count, dir){
  if(dir==='backward'){
      arr = arr.reverse();
      start = arr.length-start-1;
  }
   var lastIndex = start+count;
  return arr.slice(start,  lastIndex>arr.length?arr.length: lastIndex)
  .concat(arr.slice(0,  lastIndex>arr.length?lastIndex-arr.length: 0));
}

var arr = [0,1,2,3,4,5,6,7,8,9];
alert(overSlice(arr,7,5,'backward'));

#4


0  

Just create copy of the array and append the original array until it is long enough:

只需创建数组的副本并附加原始数组,直到它足够长:

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
var start = 7
var count = 5
var tmparr = arr

while (tmparr.length < start + count) {
   tmparr = tmparr.concat(arr);
}

var result = tmparr.slice(start, start + count);

alert(result);

#5


0  

To filter invalid positions, I add some validations, without which the code can be even shorter.

为了过滤无效位置,我添加了一些验证,没有这些验证,代码可以更短。

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
var countToExtract = 10
var whereToBegin = -1
var direction = "backword"

function overslice(array, startIndex, count, direction) {
    var retArray = [];
    var step = direction == "backword" ? -1 : 1;
    var startPos = (startIndex + array.length) % array.length;
    var endPos = (startPos + (count % array.length) * step + array.length) % array.length;

    for (var i = 0; i < count; i++) {
        var pos = (startPos + (i * step) % array.length + array.length) % array.length;
        retArray.push(array[pos]);
    }
    return retArray;
}

var lampa = overslice(arr, whereToBegin, countToExtract, direction)

alert(lampa)

with code above, you can:
begin from a minus position, which will count back from the other end.
count can be longer than array length, which will return you numbers repeatedly.

使用上面的代码,您可以:从负位置开始,这将从另一端开始计数。 count可以比数组长度长,这将重复返回数字。

#6


0  

Hi try this code .

嗨试试这个代码。

function myslice( ar , start , count , dir ) {

    dir = dir || 'F';

    var out = [] ,
        times = Math.ceil( ( start + count )/ ar.length  ) + 1;

    while( times-- ) {
        [].push.apply( out, ar );
    }

    if ( dir == 'B' ) {
        start = ar.length - start - 1;
        out = out.reverse() ;
    }

    return out.slice( start  , start+count );
}

myslice ( [0,1,2,3,4,5,6,7,8,9] , 7 , 5 , 'B' );

#1


1  

How about a function that returns the forward and back arrays? That way you don't need a switch. Something like this:

返回前向和后向数组的函数怎么样?这样你就不需要开关了。像这样的东西:

function overslice(arr, idx, items) {

  var fwd = arr.filter(function(v,i){ return i >= idx }).slice(0, items),
      back = arr.filter(function(v,i){ return i <= idx }).slice(-items);

  while (fwd.length < items) {
    fwd = fwd.concat(arr).slice(0, items);
  }

  while (back.length < items) {
    back = arr.concat(back).slice(-items);
  }

  return { fwd: fwd, back: back };
}

Then you can use it like:

然后你就可以使用它:

var array = [0,1,2,3,4,5,6,7,8,9]
var result = overslice(array, 7, 5);

console.log(result.fwd, result.back); //=> [7, 8, 9, 0, 1] [3, 4, 5, 6, 7] 

#2


1  

My approach:

function overslice(array, startindex, count, direction) {
    var retarray = [];
    var increment = (direction === 'backward') ? -1 : 1;

    for(var c=0, i = startindex; c<count; i+=increment, c++){
        retarray.push(array[(i + array.length)%array.length]);
    }
    return retarray;
}

Working fiddle

UPDATE

Another version using the count variable to dictate the direction using positive/negative values and with a fix to allow use of count larger than the array length:

另一个版本使用count变量来指示使用正/负值的方向,并使用修复来允许使用大于数组长度的计数:

function overslice(array, startindex, count) {
    var retarray = [];
    var increment = (count >= 0) ? 1 : -1;
    count = Math.abs(count);
    for(var i = startindex, c = 0;c<count;i+=increment, c++){
        if(i<0) i= array.length-1;  
        retarray.push(array[i%array.length]);
    }
    return retarray;
}

Demo fiddle

#3


0  

Its not much, but looks fine JS Bin:

它不多,但看起来很好JS斌:

function overSlice(arr, start, count, dir){
  if(dir==='backward'){
      arr = arr.reverse();
      start = arr.length-start-1;
  }
   var lastIndex = start+count;
  return arr.slice(start,  lastIndex>arr.length?arr.length: lastIndex)
  .concat(arr.slice(0,  lastIndex>arr.length?lastIndex-arr.length: 0));
}

var arr = [0,1,2,3,4,5,6,7,8,9];
alert(overSlice(arr,7,5,'backward'));

#4


0  

Just create copy of the array and append the original array until it is long enough:

只需创建数组的副本并附加原始数组,直到它足够长:

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
var start = 7
var count = 5
var tmparr = arr

while (tmparr.length < start + count) {
   tmparr = tmparr.concat(arr);
}

var result = tmparr.slice(start, start + count);

alert(result);

#5


0  

To filter invalid positions, I add some validations, without which the code can be even shorter.

为了过滤无效位置,我添加了一些验证,没有这些验证,代码可以更短。

var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
var countToExtract = 10
var whereToBegin = -1
var direction = "backword"

function overslice(array, startIndex, count, direction) {
    var retArray = [];
    var step = direction == "backword" ? -1 : 1;
    var startPos = (startIndex + array.length) % array.length;
    var endPos = (startPos + (count % array.length) * step + array.length) % array.length;

    for (var i = 0; i < count; i++) {
        var pos = (startPos + (i * step) % array.length + array.length) % array.length;
        retArray.push(array[pos]);
    }
    return retArray;
}

var lampa = overslice(arr, whereToBegin, countToExtract, direction)

alert(lampa)

with code above, you can:
begin from a minus position, which will count back from the other end.
count can be longer than array length, which will return you numbers repeatedly.

使用上面的代码,您可以:从负位置开始,这将从另一端开始计数。 count可以比数组长度长,这将重复返回数字。

#6


0  

Hi try this code .

嗨试试这个代码。

function myslice( ar , start , count , dir ) {

    dir = dir || 'F';

    var out = [] ,
        times = Math.ceil( ( start + count )/ ar.length  ) + 1;

    while( times-- ) {
        [].push.apply( out, ar );
    }

    if ( dir == 'B' ) {
        start = ar.length - start - 1;
        out = out.reverse() ;
    }

    return out.slice( start  , start+count );
}

myslice ( [0,1,2,3,4,5,6,7,8,9] , 7 , 5 , 'B' );