Pattern matching for years, I need to be able to return all years from a string.
- When there is a dash "-" I need to return all numbers between. For example, '2004-2006' should return an array of numbers [2004,2005,2006];
- If the number at the beginning of the dash is larger than the number following it, nothing should be printed out. For example '2006-2005' should return [].
- years between commas should simply be returned as long as they do not exceed the current year, and are not less than 1999. For example '1998,2020' should return an empty array [].
- There should be no duplicates and the values should be ordered.
I believe my code could be written in a more elegant and consise way.
Here are my test cases:
assert.deepEqual(parseRange('2002-2005, 2002-2005, 2002 - 2005'), [2002, 2003, 2004, 2005]);
assert.deepEqual(parseRange('2017'), [2017]);
assert.deepEqual(parseRange('2017 - 2015'), []);
assert.deepEqual(parseRange('2015 - 2015'), [2015]);
assert.deepEqual(parseRange('1999 , 2000, , 2008'), [1999, 2000, 2008]);
assert.deepEqual(parseRange('2015, 2014, 2010'), [2010, 2014, 2015]);
assert.deepEqual(parseRange('1999, 3000'), [1999]);
assert.deepEqual(parseRange('1998, 2020'), []);
Here is my working Code
function parseRange(string) {
return [...new Set(string.split(',').map(range => range.includes('-') ? range.split('-').map(num => +num) : +range)
.filter(set => Array.isArray(set) ? set[0] <= set[1] : set > 1998 && set <= new Date().getFullYear()).reduceRight((arr, val) =>
arr.concat(Array.isArray(val) ? Array(val[1] - val[0] + 1).fill().map((_, num) => val[0] + num) : val), []))].sort();
}
console.log(parseRange('2002-2005, 2002-2005, 2002 - 2005'));
console.log(parseRange('2017'));
console.log(parseRange('2017 - 2015'));
console.log(parseRange('2015 - 2015'));
console.log(parseRange('1999 , 2000, , 2008'));
console.log(parseRange('2015, 2014, 2010'));
console.log(parseRange('1999, 3000'));
console.log(parseRange('1998, 2020'));