Javascript - 如何在某个索引处启动 forEach 循环

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43295840/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:49:15  来源:igfitidea点击:

Javascript - how to start forEach loop at some index

javascriptarrays

提问by Leff

I have an array with alot of items, and I am creating a list of them. I was thinking of paginating the list. I wonder how can I start a forEachor forloop at some indexin an array, that would be in my example the number of items in the list on each page, so that I don't need to iterate over the whole array in each loop?

我有一个包含很多项目的数组,我正在创建一个列表。我正在考虑对列表进行分页。我想知道如何在数组中的某个位置启动forEachorfor循环,index在我的示例中是每个页面上列表中的项目数,这样我就不需要在每个循环中遍历整个数组?

arr.forEach(function (item) {
  someFn(item);
})


for (var i = 0, len = arr.length; i < len; i++) {
  someFn(arr[i]);
}

采纳答案by Nina Scholz

You could use a copy of the array, by using Array#slice

您可以使用数组的副本,通过使用 Array#slice

The slice()method returns a shallow copy of a portion of an array into a new array object selected from begin to end (end not included). The original array will not be modified.

slice()方法将数组的一部分的浅拷贝返回到从开始到结束(不包括结束)选择的新数组对象中。不会修改原始数组。

array.slice(10, 20).forEach(someFn); // only for functions which respects API of forEach*

* parameters for a callback

*回调参数

Or you can start at a given index and end at a given index.

或者您可以从给定的索引开始并在给定的索引处结束。

for (var i = 10, len = Math.min(20, arr.length); i < len; i++) {
    someFn(arr[i]);
}

With

Math.min(20, arr.length)

returns a value, if the array is smaller than the given value 20. For example if the array has only index 0 ... 14, you get as result 15.

如果数组小于给定值,则返回一个值20。例如,如果数组只有索引 0 ... 14,则结果为 15。

回答by T.J. Crowder

forEachdoesn't offer that feature, no. So your choices are:

forEach不提供该功能,不。所以你的选择是:

  1. A simple forloop

  2. Ignoring the indexes you don't want to handle (as in Kind user's answer)

  3. Using slice(as in Nina's answer)

  4. Writing your own function

  1. 一个简单的for循环

  2. 忽略您不想处理的索引(如Kind 用户的回答

  3. 使用slice(如尼娜的回答

  4. 编写自己的函数

Here's #4 as an Array.prototypeextension (non-enumerable, of course; adding enumerable properties to Array.prototypebreaks a lotof code); after it is a standalone version for when adding to Array.prototypeisn't appropriate:

这是#4 作为Array.prototype扩展(当然是不可枚举的;添加可枚举属性来Array.prototype破坏大量代码);在它是独立版本之后,添加到Array.prototype不合适时:

// Giving ourselves the function
Object.defineProperty(Array.prototype, "myEach", {
  value: function(from, to, callback, thisArg) {
    if (typeof from === "function") {
      thisArg = callback;
      callback = to;
      to = from;
      from = 0;
    }
    if (typeof to === "function") {
      thisArg = callback;
      callback = to;
      to = this.length;
    }
    for (var n = from; n < to; ++n) {
      callback.call(thisArg, this[n], n, this);
    }
  }
});

// Using it:
var arr = ["zero", "one", "two", "three", "four", "five", "six", "seven"];
console.log("*** From 3:");
arr.myEach(3, function(e) { console.log(e); });
console.log("*** From 3 (inclusive) to 5 (exclusive):");
arr.myEach(3, 5, function(e) { console.log(e); });
console.log("*** All:");
arr.myEach(function(e) { console.log(e); });
console.log("*** Check thisArg handling on 0-2:");
var o = {answer: 42};
arr.myEach(0, 2, function(e) {
  console.log(e + " (this.answer = " + this.answer + ")");
}, o);
.as-console-wrapper {
  max-height: 100% !important;
}

Again note that that's a non-enumerableproperty, which is vital if you ever add anything to Array.prototype(otherwise, you break a lot of code).

再次注意,这是一个不可枚举的属性,如果您向其中添加任何内容,这一点至关重要Array.prototype(否则,您会破坏大量代码)。

You wouldn't do that in a library to be consumed by others, you'd just have a standalone function:

您不会在供其他人使用的库中这样做,您只需要一个独立的功能:

// Giving ourselves the function
function myEach(array, from, to, callback, thisArg) {
  if (typeof from === "function") {
    thisArg = callback;
    callback = to;
    to = from;
    from = 0;
  }
  if (typeof to === "function") {
    thisArg = callback;
    callback = to;
    to = array.length;
  }
  for (var n = from; n < to; ++n) {
    callback.call(thisArg, array[n], n, array);
  }
}

// Using it:
var arr = ["zero", "one", "two", "three", "four", "five", "six", "seven"];
console.log("*** From 3:");
myEach(arr, 3, function(e) {
  console.log(e);
});
console.log("*** From 3 (inclusive) to 5 (exclusive):");
myEach(arr, 3, 5, function(e) {
  console.log(e);
});
console.log("*** All:");
myEach(arr, function(e) {
  console.log(e);
});
console.log("*** Check thisArg handling on 0-2:");
var o = {answer: 42};
myEach(arr, 0, 2, function(e) {
  console.log(e + " (this.answer = " + this.answer + ")");
}, o);
.as-console-wrapper {
  max-height: 100% !important;
}

回答by kind user

Unfortunately Array#forEachiterates over every element in the given array, but you could apply a simple condition to determine to which elements (with specified index) apply the given function.

不幸的是Array#forEach迭代给定数组中的每个元素,但您可以应用一个简单的条件来确定哪些元素(具有指定索引)应用给定函数。

i > 3 ? someFn(item) : null;
^ if index more than 3 - call the function

var arr = [1,2,3,4,5,6,7];

function someFn(elem){
  console.log(elem);
}

arr.forEach(function(item, i) {
  return i > 3 ? someFn(item) : null;
})

回答by xragdollqueen

Thinking on what @NinaScholz commented, perhaps you can use variables and any changes would be set in those instead of changing the loop.

想想@NinaScholz 评论的内容,也许您可​​以使用变量,并且可以在其中设置任何更改,而不是更改循环。

function someFn(item, array2){
  array2.push(item, array2);
}

var arrayItems1 = [1,2,3,4,5,6,7,8,9,10];
var arrayItems2 = [];

var firstIndex = 1;
var lastIndex = 5;
var i = 0;

for (i = firstIndex; i < lastIndex; i++){
     someFn(arrayItems1[i], arrayItems2);
}

alert(arrayItems2.join(' '));

回答by elpddev

You could apply some kind of implementation of the iterator pattern.

您可以应用某种迭代器模式的实现。

var Iterator = function (list, position) {
  return {
    isNext: function () {
      return position + 1 < list.length;
    },
    isDefined: function () {
      return (position < list.length && position >= 0);
    },
    element: function () {
      return list[position];
    },
    position: function () {
      return position;
    },
    moveNext: function () {
      if (this.isNext()) { return Iterator(list, position + 1); }
      return Iterator([], 0);
    }      
}

Iterator.forEach = function (action, iterator, length) {
  var counter = 0;
  while (counter < length && iterator.isDefined()) {
    counter = counter + 1;
    action(iterator.element(), iterator.position());
    iterator = iterator.moveNext();
  }

  return iterator;
}   

And then have an iterator to use for going over the list and keep the state of the last iteration over a list.

然后有一个迭代器用于遍历列表并保持列表上最后一次迭代的状态。

var list = [1, 3, 5, 3, 6];
var iterator = Iterator(list, 0);

iterator = Iterator.forEach(function (element, index) {
  console.log(element, index);
}, iterator, 3);

//1 0
//3 1
//5 2

Iterator.forEach(function (element, index) {
   console.log(element, index);              
}, iterator, 5);

//3 3
//6 4

回答by Pacerier

array.values()to get the iterator, .next()it and use it.

array.values()获取迭代器,.next()它并使用它。

let ar=[1,2,3,4]

var _;for(let a of(_=ar.values(),_.next(),_)){
  console.log(a)
}