3

in my for element of array loop, I want to access the elements besides the current one. Specifically, the previous or next element. I would also like this to reach across the first/last element barrier. How can this be achieved?

ie. given:

my_fruits = ['apple', 'banana', 'grapes', 'blueberries']

for (const fruit of my_fruits) {
    // When fruit === 'banana', I want to access 'apple', 
    // when fruit === 'blueberries' I want to access 'grapes'.
    // Also when it's the last element, I want to acknowledge that and access the first. 
}

Due to how I'm dealing with async/await in this local, .forEach is something I'd prefer to avoid.

Thanks

jsarbour
  • 928
  • 1
  • 8
  • 20
  • The question is: do you really want to use `for of`. If so, you have no direct access to the index, although you actually want to use it, so the solutions won't be very elegant. If you don't need `for of`, use a classic `for` loop or use `for in` or `forEach`. – sjahan Jun 07 '19 at 14:42
  • yeah looks like a 'classic' loops is going to be the way to go here – jsarbour Jun 07 '19 at 14:43
  • Do you want to get all the time the previous one or for specifics ones like `banana` and `blueberries` ? – Cid Jun 07 '19 at 14:47
  • always the previous element, and for the first and last to have the last and first, respectively – jsarbour Jun 07 '19 at 14:48

6 Answers6

6

You should use forEach loop and use the second parameter which is index.

const arr = ['apple', 'banana', 'grapes', 'blueberries']

arr.forEach((x,i) => {
  let prev = i > 0 ? arr[i - 1] : null;
  let next = i < arr.length ? arr[i + 1] : null;
  
  console.log(`current:${x} next:${next} previous: ${prev}`)
})

If you don't want to use forEach you can use for..in. But besure about this you are not adding any properties other than indexes on the array.

const arr = ['apple', 'banana', 'grapes', 'blueberries']
for(let i in arr){
  console.log(`current:${arr[+i]} next:${arr[+i+1]} previous: ${arr[+i-1]}`)
}
Maheer Ali
  • 35,834
  • 5
  • 42
  • 73
  • My `for of` is inside an async function, and contains await calls, and so things are much cleaner if I avoid a `.forEach`. If there's another solution that avoids a `.forEach` I'd prefer to use that. – jsarbour Jun 07 '19 at 14:43
  • 1
    @jsarbour Well you can use classic loops. Or you could use `for..in`. If you are sure that there are no other properties of the array. – Maheer Ali Jun 07 '19 at 14:45
  • 1
    @jsarbour, this kind of information should have been in the question... – trincot Jun 07 '19 at 14:45
  • yes, my apologies, I didn't remember that it was relevant until it came up. Should I edit and add it? – jsarbour Jun 07 '19 at 14:46
  • 1
    [don't use `for..in` with arrays](https://stackoverflow.com/questions/500504/why-is-using-for-in-with-array-iteration-a-bad-idea) `for(let i=0; i – Thomas Jun 07 '19 at 14:50
5

You could use forEach. The third parameter of the callback function is the array. So, you could destructure it to get the [i-1] and [i+1] th items

const my_fruits = ['apple', 'banana', 'grapes', 'blueberries']

my_fruits.forEach((item, i, { [i-1]: prev, [i+1]: next }) => {
  console.log(item, prev, next)
})
adiga
  • 34,372
  • 9
  • 61
  • 83
  • 1
    really nice. I'd like to +1, but it doesn't fit the question anymore after OP clarified that he doesn't want to use `forEach` – Thomas Jun 07 '19 at 14:56
2
You can access the index of the current element. 

var my_fruits = ['apple', 'banana', 'grapes', 'blueberries']

for (const [index,value] of my_fruits.entries()) {
   if(index) console.log(my_fruits[index-1])
}
Monica Acha
  • 1,076
  • 9
  • 16
1

You can use a regular for (let i = 0; i < len; i++)

let my_fruits = ['apple', 'banana', 'grapes', 'blueberries'];

for (let i = 0, len = my_fruits.length; i < len; i++)
{
    if (i == 0)
    {
        console.log("I am at first iteration. The last item is : "+ my_fruits[len - 1]);
    }
    if (i > 0)
    {
        console.log("I have now : " + my_fruits[i] + " and I have access to " + my_fruits[i - 1]);
    }
    if (i + 1 == len)
    {
        console.log("I am at last iteration. The first item is : "+ my_fruits[i - 1]);
    }
}
Cid
  • 14,968
  • 4
  • 30
  • 45
1

I hope that what You need

const my_fruits = ['apple', 'banana', 'grapes', 'blueberries']

for (let fruit in my_fruits) {

  fruit = parseInt(fruit);

   if (! my_fruits[fruit + -1]) {

      console.log(my_fruits[0] + " => " + my_fruits[fruit + my_fruits.length - 1]);

   } else {

      console.log(my_fruits[fruit] + " => " + my_fruits[fruit + -1]);

    }
}
Refat Alsakka
  • 561
  • 2
  • 11
0

const arr = ['apple', 'banana', 'grapes', 'blueberries']

arr.forEach((x,i) => {
  let prev = i > 0 ? arr[i - 1] : null;
  let next = i + 1 < arr.length ? arr[i + 1] : null;
  
  console.log(`current:${x} next:${next} previous: ${prev}`)
})

I used Maheer Ali's code above, but I had to make a change. I put i + 1 < arr.length instead of i < arr.length because otherwise it always returns true (the index, starting from 0, will always be less than the length of the array, if it exists).