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
forEach
doesn't offer that feature, no. So your choices are:
A simple for
loop
Ignoring the indexes you don't want to handle (as in Kind user's answer)
Using slice
(as in Nina's answer)
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;
}
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.
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(' '));
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;
})
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
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)
}