简体   繁体   中英

How to loop through an array of strings backwards x amount of times and start over when the end is reached?

I am trying to loop through an array of months 11 times backwards. Basically I have a current month (September 2019) and I want to go back 11 months thus ending up at October 2018. I have looked at so many code snippets but none capture the whole 'starting over' portion. The point of it all is to push these months into a dropdown menu. Thus having the current month and the previous 11 months.

I have already tried this code snippet. It just goes forward. When I set it up to where it goes backwards there is this endless loop that kills my Chrome.

Here is what I have so far:

var monthNames = ["January", "February", "March", "April", "May", "June",
  "July", "August", "September", "October", "November", "December"
];
var d = new Date();
console.log(d.getMonth() + " is the index");

var index = monthNames[d.getMonth()];
console.log(index + ' is the month');
let monthIndex = monthNames.indexOf(index);
var n = 11

var result = [];

for (var i = monthIndex, len = monthNames.length; i <= monthIndex + n; i++) {
    result.push(monthNames[(i + len) % len]);
}


console.log(result.join(", "));

It is going forwards in months when I want it to start at September and go backwards and end up at October.

Any help is appreciated. Thank you!

You could take the actual month as offset and subtract the index and get the rest with the remainder for the value of the month names.

 var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], offset = new Date().getMonth(), length = 12, result = Array.from({ length }, (_, i) => monthNames[(12 + offset - i) % 12]); console.log(result.join(", ")); 

If you want a Python-like logic, you can try JavaScript Proxies :

 const monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; const months = new Proxy(monthNames, { get(target, prop) { if (!isNaN(prop)) { prop = parseInt(prop, 10); if (prop < 0) { prop += target.length; } } return target[prop]; } }) let d = new Date() let start = d.getMonth() - 1 let n = 11 let end = start - n, result = [] for(let c = start; c >= end; c--){ result.push(months[c]) } console.log(result.join(", ")) 

This way you will only need the starting month and subtract 11 from itself, and you can easily call that range from months . (eg start 5, end 5-11)

One approach that works is to subtract one from the index each time, checking when you're at 0 to loop back to the end, and stop the loop when you get to one more than the starting point. Note that this will bring the loop to a premature end because your ending condition is true at the start - so you need to start at one less than that, having prepopulated the array with the current month.

I've also removed a lot of the unnecessary repetitions in your original code. The below is, I freely admit, not particular elegant, but it works and should be easily understandable.

 var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; var startMonth = new Date().getMonth(); var result = [monthNames[startMonth]]; if (startMonth == 0) { startMonth = monthNames.length; } for (var i = startMonth - 1; i != startMonth; i = (i == 0) ? monthNames.length : (i - 1)) { result.push(monthNames[i]); } console.log(result.join(", ")); 

Keep it simple:

const monthNames = ["January", "February", "March", "April", "May", "June",
  "July", "August", "September", "October", "November", "December"
];


const octoberIndex = monthNames.findIndex(month => month === "October");
const monthsFromOctoberToSeptember = monthNames.slice(octoberIndex, monthNames.length)
.concat(monthNames.slice(0, octoberIndex));

const result = monthsFromOctoberToSeptember.reverse();

console.log(result.join(', '));

September, August, July, June, May, April, March, February, January, December, November, October

Not much different than what suggested above but bit simpler to understand

var monthNames = ["January", "February", "March", "April", "May", "June",
  "July", "August", "September", "October", "November", "December"
];
var currentDate = new Date();
var currentMonthIndex = currentDate.getMonth();
var result = [];
var monthLength = 12;

for (var i = currentMonthIndex; i < monthLength; i--) {
  result.push(monthNames[i]);

  if (result.length === monthLength) {
    break;
  }

  if (i === 0) {
    i = monthLength;
  }  
}


console.log(result.join(", "));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM