Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Get range of months from array based on another array JavaScript
Suppose we have two arrays of strings. The first array contains exactly 12 strings, one for each month of the year like this:
const year = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec']; console.log(year);
[ 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec' ]
The second array contains exactly two strings, denoting a range of months like this:
const monthsRange = ["aug", "oct"]; console.log(monthsRange);
[ 'aug', 'oct' ]
We need to write a JavaScript function that takes in two such arrays and picks all the months from the first array that fall in the range specified by the second array. Note that the closing element of the range is excluded from the output.
Basic Implementation
const year = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
const range = ['aug', 'dec'];
const getMonthsInRange = (year, range) => {
const start = year.indexOf(range[0]);
const end = year.indexOf(range[1] || range[0]);
if (start <= end) {
return year.slice(start, end);
} else {
// Handle wrap-around case (e.g., 'nov' to 'feb')
return year.slice(start).concat(year.slice(0, end));
}
};
console.log(getMonthsInRange(year, range));
[ 'aug', 'sep', 'oct', 'nov' ]
Handling Edge Cases
The function also handles wrap-around cases where the range spans across the year boundary:
const year = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
const getMonthsInRange = (year, range) => {
const start = year.indexOf(range[0]);
const end = year.indexOf(range[1] || range[0]);
if (start <= end) {
return year.slice(start, end);
} else {
return year.slice(start).concat(year.slice(0, end));
}
};
// Regular range
console.log("Aug to Dec:", getMonthsInRange(year, ['aug', 'dec']));
// Wrap-around range (Nov to Feb)
console.log("Nov to Feb:", getMonthsInRange(year, ['nov', 'feb']));
// Single month
console.log("Just Aug:", getMonthsInRange(year, ['aug', 'sep']));
Aug to Dec: [ 'aug', 'sep', 'oct', 'nov' ] Nov to Feb: [ 'nov', 'dec', 'jan' ] Just Aug: [ 'aug' ]
Improved Version with Validation
const year = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'];
const getMonthsInRange = (monthsArray, range) => {
// Validate inputs
if (!Array.isArray(monthsArray) || !Array.isArray(range) || range.length !== 2) {
return [];
}
const start = monthsArray.indexOf(range[0]);
const end = monthsArray.indexOf(range[1]);
// Check if both months exist in the array
if (start === -1 || end === -1) {
return [];
}
if (start <= end) {
return monthsArray.slice(start, end);
} else {
return monthsArray.slice(start).concat(monthsArray.slice(0, end));
}
};
// Test various scenarios
console.log("Mar to Jun:", getMonthsInRange(year, ['mar', 'jun']));
console.log("Invalid month:", getMonthsInRange(year, ['xyz', 'jun']));
console.log("Same month:", getMonthsInRange(year, ['may', 'may']));
Mar to Jun: [ 'mar', 'apr', 'may' ] Invalid month: [] Same month: []
How It Works
The function uses indexOf() to find the positions of the start and end months in the array. If the start position is less than or equal to the end position, it uses slice(start, end) to extract the range. For wrap-around cases (like November to February), it concatenates two slices: from start to end of array, and from beginning to end position.
Conclusion
This solution efficiently extracts month ranges from arrays, handling both normal and wrap-around cases. The slice() method naturally excludes the end month, making it perfect for range operations.
