AFerrara
AFerrara

Reputation: 429

How to loop through/wrap around an array based on starting index?

var ZODIAC = ["RAT", "OX", "TIGER", "RABBIT", "DRAGON", "SNAKE", "HORSE", "SHEEP", "MONKEY", "ROOSTER", "DOG", "PIG"];
var STARTING_ZODIAC = "MONKEY";

How can I print all the elements in this array starting with Monkey and finishing with sheep?

Upvotes: 6

Views: 13046

Answers (5)

vol7ron
vol7ron

Reputation: 42179

What seems most straightforward to me is a do-while loop, starting at the index and then wrapping until you get back to that index. This is one case where it makes sense to use a do-block to keep things simple:

const ZODIAC = ["RAT", "OX", "TIGER", "RABBIT", "DRAGON", "SNAKE", "HORSE", "SHEEP", "MONKEY", "ROOSTER", "DOG", "PIG"];
const STARTING_ZODIAC = "MONKEY";

let i = start_ndx = ZODIAC.indexOf(STARTING_ZODIAC);

do {
  console.log(i, ZODIAC[i++])
  i == ZODIAC.length && (i=0)
} while (i!==start_ndx)

Comment: To me, most other answers seem unnecessarily complex (using modulo), or inefficient (copying values and new arrays); where as seen abvoe, both can be avoided, which in my perspective is easier to maintain

Upvotes: 0

Ken Y-N
Ken Y-N

Reputation: 15018

6 answers, but none of them use the obvious to me solution:

for (let i = 0; i < ZODIAC.length; i++) {
   console.log(ZODIAC[(startIndex + i) % ZODIAC.length]);
}

Loop 12 times, and use the modulus operator so we can count 4, 5, ... 10, 11, 0, 1, 2, 3.

Upvotes: 8

puddi
puddi

Reputation: 811

Another fun way to solve it:

let doubleZodiac = ZODIAC.concat(ZODIAC);
let start = ZODIAC.indexOf(STARTING_ZODIAC);

for (let i = 0; i < ZODIAC.length; i++) {
  console.log(doubleZodiac[start + i]);
}

This adds a copy of the array to the end, and then just prints 12 from the starting index.

Upvotes: 0

CertainPerformance
CertainPerformance

Reputation: 371233

You can use the modulo operator so that your index variable wraps around to 0 once it reaches the length of the ZODIAC array:

const ZODIAC = ["RAT", "OX", "TIGER", "RABBIT", "DRAGON", "SNAKE", "HORSE", "SHEEP", "MONKEY", "ROOSTER", "DOG", "PIG"];
const STARTING_ZODIAC = "MONKEY";
const startIndex = ZODIAC.indexOf(STARTING_ZODIAC);

console.log(STARTING_ZODIAC);
for (let i = startIndex + 1; i !== startIndex; i = (i + 1) % ZODIAC.length) {
  console.log(ZODIAC[i]);
}

Another method would be to slice the two parts of the array into the proper order first:

const ZODIAC = ["RAT", "OX", "TIGER", "RABBIT", "DRAGON", "SNAKE", "HORSE", "SHEEP", "MONKEY", "ROOSTER", "DOG", "PIG"];
const STARTING_ZODIAC = "MONKEY";
const startIndex = ZODIAC.indexOf(STARTING_ZODIAC);

[
   ...ZODIAC.slice(startIndex),
   ...ZODIAC.slice(0, startIndex)
].forEach(str => console.log(str));

Upvotes: 13

Matthew Herbst
Matthew Herbst

Reputation: 32053

Easy enough, just print from the start to the end of the array, and then from beginning of the array to the start.

function printZodiacs(startingZodiac, zodiacs) {
  const startIndex = zodiacs.indexOf(startingZodiac);

  // start to end of array
  for (let i = startIndex; i < zodiacs.length; i++) {
    console.log(zodiacs[i]);
  }

  // beginning of array to to start
  for (let i = 0; i < startIndex; i++) {
    console.log(zodiacs[i]);
  }
}

printZodiacs(STARTING_ZODIAC, ZODIAC);

Upvotes: 0

Related Questions