I'm trying to have a forEach loop over an array, but only the last few entries.
I'd know how to do this in a for loop, that'd look a bit like this:
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
/* This will loop over the last 3 entries */
for(var x = arr.length; x >= 7; x--){
console.log(arr[x]);
}
Would there be any way of achieving the same results in a forEach loop?
You can use slice() and reverse() methods and then forEach() loop on that new array.
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.slice(-3).reverse().forEach(e => console.log(e))
This is how you do it with forEach loop:
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.forEach((element, index) => {
if(index>7) console.log(arr[index]);
})
You could take a classic approach by taking the count of the last elements and use it as counter and an offset for the index.
Then loop with while by decrementing and checking the counter.
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
last = 3,
offset = array.length - last;
while (last--) {
console.log(array[last + offset]);
}
Related
for learning purposes I want to get every second element of an array. I succeeded with a for loop:
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
function filterEverySecond(arr) {
let everySecondEl = [];
for (let i = 0; i < arr.length; i += 2) {
everySecondEl.push(arr[i]);
}
return everySecondEl;
}
console.log({
numbers,
result: filterEverySecond(numbers)
});
Now I want to achieve the same without a for loop, but by using array methods (forEach, filter, map or reduce). Can anyone recommend which method would be best here?
you can do it easily with filter
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const filtered = numbers.filter((_, i) => i % 2 === 0)
console.log(filtered)
you just filter out the elements that have a odd index
You can use filter and check if the index of the current array element is divisible by 2:
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log({
numbers,
result: numbers.filter((_, index) => index % 2 === 0)
});
You can use filter for index.
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log({
numbers,
result: numbers.filter((n,i)=>i%2==0)
});
You could use a for each loop like so to get the same desired output:
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const result = [];
numbers.forEach(number => {
if (number % 2 != 0) {
result.push(number);
}
});
console.log(numbers);
console.log(result);
The modulus operator returns the remainder of the two numbers when divided. For example: 1 % 2 will return 1 as the remainder. So in the if statement we are checking if the number is not divisible by 2.
I would like to loop backwards in a array in javascript and then get the index of each element in the array for example if a array has 10 elements and is looped backwards it would log 9, 8, 7, 6, 5, 4, 3, 2, 1, 0. for some werid reason i am getting a bunch of negaitive -1s and im confused why it wont just return the index properly.
here is the code
//Arrays I would like to pass into the function
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];
function validateCred(arr) {
let sum = 0;
for (let i = arr.length - 1; i >= 0; i--) {
console.log(arr.indexOf(i));
}
}
console.log(validateCred(valid1));
why -1s?
It is because of arr.indexOf(i) when the loop starts i=15 so:
arr.indexOf(15) will return -1 because you don't have a 15 in your array.
next i=14 same as above.
.
.
.
i=9 then it will find the element at index 3.
As UnholySheep explains above, Array.indexOf(i) gives you the index of the first occurrence of the value represented by i in the array. Here is some code to help you debug:
function validateCred(arr) {
let sum = 0
for (let i = arr.length - 1; i >= 0; i--) {
console.log(i) // log the index
console.log(arr[i]) // log the value
}
}
With an array of: [1, 2, 3, 4, 5, 6]
I would like to delete between 2 indices such as 2 and 4 to produce [1, 2, null, null, 5, 6]. What's the easiest way to do this?
Hopefully better than this:
const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
let i = 2;
const rangeEnd = 9;
while (i < rangeEnd) {
delete array[i];
i++;
}
console.log(array)
If you want to use some native API you can actually do this with splice(). Otherwise, you should iterate a for loop through your array and change the value in each iteration.
Here is an example of how it would be done:
const array = [1, 2, 3, 4, 5, 6]
array.splice(3, 2, null, null) // the First element is beginning index and the second is count one will indicate how many indexes you need to traverse from the first one, then you should provide replace element for each of them.
console.log(array)
Note: For more info about it you can read more here.
There is a possible workaround for large scale replacement, so I will give it a touch here:
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var anotherArr = Array(2).fill(null); // or you can simply define [null, null, ...]
Array.prototype.splice.apply(arr, [3, anotherArr.length].concat(anotherArr));
console.log(arr);
As you mean the range (2, 4] so you can follow this:
The range is: lower limit exclusive and the upper limit inclusive.
const arr = [1, 2, 3, 4, 5, 6];
const deleteRange = (arr, f, t) => {
return arr.map((item, i) => {
if (i + 1 > f && i + 1 <= t) {
return null;
}
return item;
})
}
console.log(deleteRange(arr, 2, 4));
Why does the remaining in original array = [1, 3, 5, 7, 9]
Since arr.splice(i, 1) = i is the target index and 1 is the number of item to be removed, i is increases to 10 respectively from i++ which short for i = i + 1, So why does it remove 5 index and remain 5 in the array ? that's what i know so far and i have struggled to read the docs but still have no idea to understand, please explain it for me
let arr = [1,2,3,4,5,6,7,8,9,10];
for(let i = 1; i < arr.length; i++) {
arr.splice(i, 1);
}
It is because the length of arr decreases everytime splice function runs.
Here is how the array changes.
[2, 3, 4, 5, 6, 7, 8, 9, 10]
[2, 4, 5, 6, 7, 8, 9, 10]
[2, 4, 6, 7, 8, 9, 10]
[2, 4, 6, 8, 9, 10]
[2, 4, 6, 8, 10]
So every loop, i increases and arr.length decreases by 1. so only 5 loops runs and the result is [2, 4, 6, 8, 10]
You're wondering why it's removing 1, 3, 5, 7, and 9, right?
Here's why. As the for loop iterates, i keeps increasing by one.
HOWEVER, by calling .splice, you are removing the first element of the array, so as a result, every other element moves down an index.
Let's play this out step by step for a few iterations of the for loop.
i = 0; arr.splice(0, 1) removes 1, so arr is [2, 3, 4, 5, 6, 7, 8, 9, 10]
i = 1; arr.splice(1, 1) removes 3, not 2, because now 3 is at index 1 of arr. Performing the splice leaves arr as [2, 4, 5, 6, 7, 8, 9, 10].
i = 2; arr.splice(2, 1) removes 5, because 5 is currently at index 2. As a result, arr becomes [2, 4, 6, 7, 8, 9, 10].
Is it clear now what's going on?
If your goal is to successively remove each element, one at a time, then instead of calling .splice(i, 1) in each iteration of the loop, you should call .splice(0, 1), since the value at index 0 changes each time you call .splice.
Remember, arrays are 0 based. Second, the length is changing each time it evaluates.
MDN links:
Splice
Map
So you may want to try
i =< length
Where length is determined and is set ahead of time and constant. You can try mapping the array to a new one, so the original array stays pure and unaffected by the splice.
You need to check the for loop end condition, i is not increasing to 10. Why? because i < arr.length.
So it will like this :
Iteration 1:
i=0; arr.length = 10; arr = [1,2,3,4,5,6,7,8,9,10]; ==> result [2,3,4,5,6,7,8,9,10];
Iteration 2:
i=1; arr.length = 9; arr = [2,3,4,5,6,7,8,9,10]; ==> result [2,4,5,6,7,8,9,10];
Iteration 3:
i=2; arr.length = 8; arr = [2,4,5,6,7,8,9,10]; ==> result [2,4,6,7,8,9,10];
.
.
.and so forth
i = 5 ==> arr.length: 5 ==> final result : [2, 4, 6, 8, 10]
So if you want to delete all items using splice:
let arr = [1,2,3,4,5,6,7,8,9,10];
while(arr.length > 0) {
arr.splice(0, 1);
}
I have an array and would like to sort all but the last n elements.
For example, if the array is 10 elements long, would like elements 0 through 7 to be sorted while elements 8-9 are left in place.
var array = [5, 2, 6, 4, 1, 9, 3, 8, 7];
array = array.slice(0, 7).sort().concat(array.slice(7, 10));
// array is now [1, 2, 3, 4, 5, 6, 9, 8, 7]
If you need to sort the array in place (i.e. without creating a new, sorted array), which is what the sort() method does, you could do the following:
var array = [5, 2, 6, 4, 0, 1, 9, 3, 8, 7];
var unsorted = array.slice(7);
array.length = 7;
array.sort().push.apply(array, unsorted);
More generally, here's a function to sort a portion of an array in place. Like the sort() method, it also returns a reference to the array.
function partialSort(arr, start, end) {
var preSorted = arr.slice(0, start), postSorted = arr.slice(end);
var sorted = arr.slice(start, end).sort();
arr.length = 0;
arr.push.apply(arr, preSorted.concat(sorted).concat(postSorted));
return arr;
}
Example:
var array = [5, 2, 6, 4, 0, 1, 9, 3, 8, 7];
partialSort(array, 0, 7);
An ES6 riff on the solution provided by #darin
let subSort = (arr, i, n, sortFx) => [].concat(...arr.slice(0, i), ...arr.slice(i, i + n).sort(sortFx), ...arr.slice(i + n, arr.length));
i is the index where the subsection begins
n is the number of elements to sort
sortFx is the sorting function
So it's possible to sort a range within an array:
var array = [5, 2, 6, 4, 1, 9, 3, 8, 7];
// sort array beginning at index 2; sort 4 elements of array
subSort(array, 2, 4, (a, b) => a - b);
// array is now [5, 2, 1, 4, 6, 9, 3, 8, 7]
subSort(array, 2, 4, (a, b) => b - a);
// array is now [5, 2, 9, 6, 4, 1, 3, 8, 7]
subSort() can be used for objects of arbitrary complexity.
let arr = [2, 1, 5, 4, 3];
arr = [...arr.slice(0, 2), ...arr.slice(2).sort((a, b) => a - b)];
After sorting a sub-array the original array will be [2, 1, 3, 4, 5]