Javascript - how to start forEach loop at some index

前端 未结 6 1594
予麋鹿
予麋鹿 2021-01-04 00:31

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 forEach or for

相关标签:
6条回答
  • 2021-01-04 00:57

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

    1. A simple for loop

    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

    Here's #4 as an Array.prototype extension (non-enumerable, of course; adding enumerable properties to Array.prototype breaks a lot of code); after it is a standalone version for when adding to Array.prototype isn't appropriate:

    // 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-enumerable property, which is vital if you ever add anything to Array.prototype (otherwise, you break a lot of code).

    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;
    }

    0 讨论(0)
  • 2021-01-04 00:58

    You could use a copy of the array, by using 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.

    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.

    0 讨论(0)
  • 2021-01-04 01:00

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

    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(' '));

    0 讨论(0)
  • 2021-01-04 01:06

    Unfortunately Array#forEach iterates 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.

    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;
    })

    0 讨论(0)
  • 2021-01-04 01:11

    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
    
    0 讨论(0)
  • 2021-01-04 01:17

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

    let ar=[1,2,3,4]
    
    var _;for(let a of(_=ar.values(),_.next(),_)){
      console.log(a)
    }

    0 讨论(0)
提交回复
热议问题