beerwin
beerwin

Reputation: 10327

Is there a better method of creating a list of quarters by counting back from a given quarter?

I have done this function which creates an array of quarters, counting back x quarters including from specified quarter.

The last item in the array is the reference quarter.

For example, with reference quarter 2 and a count of 9, this would yield [2, 3, 4, 1, 2, 3, 4, 1, 2];

My function works, but I would like to know, if there is a simpler, more elegant solution to this.

Code below:

/// Counts back x from specified quarter
/// Parameters:
/// @param countFrom   -- the reference quarter to count back from
/// @param count       -- count
///
/// @returns array     -- the array of quarters
function getQuarterList(countFrom, count) {
	var ret = [];
	for (var i = 0; i < count; i++){
		var z = countFrom - i;
		while (z < 1) {
			z = z + 4;
		}
		ret.splice(0, 0, z);
	}

	return ret;
}

var quarterList = getQuarterList(2, 9);
console.log(quarterList);

Upvotes: 2

Views: 118

Answers (4)

Redu
Redu

Reputation: 26191

I would do this job as follows;

var quarters = (n,m) => Array(...Array(m - m%4 + n%4)).map((e,i) => i%4 + 1)
                                                      .slice(this.length-m);
console.log(quarters(2,9));

Well thinking further i believe i can not get any more functional than this.

var quarters = (n,m) => Array(...Array(m)).map((e,i) => (Math.abs(m%4-n) + i)%4 + 1);
console.log(quarters(1,11));
console.log(quarters(3,7));
console.log(quarters(2,9));

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386756

You could calculate the start value

function getQuarterList(countFrom, count) {
    var offset = (countFrom - count) % 4 + 4;
    return Array.apply(null, { length: count }).map(function (_, i) {
        return (i + offset) % 4 + 1;
    });
}

console.log(getQuarterList(2, 9));
console.log(getQuarterList(3, 7));
console.log(getQuarterList(1, 2));
console.log(getQuarterList(4, 9));

Upvotes: 1

Bergi
Bergi

Reputation: 665276

That while loop can be omitted if you just use countFrom as the counter:

function getQuarterList(countFrom, count) {
    // assert: countFrom ∈ [1..4]
    var ret = [];
    for (var i = 0; i < count; i++) {
        ret.unshift(countFrom)
        countFrom--;
        if (countFrom < 1)
            countFrom += 4;
    }
    return ret;
}

An easier approach would be to compute which value to start at and use the module operator:

function getQuarterList(countFrom, count) {
    var ret = [];
    var z = (countFrom - count % 4 + 4) % 4;
    for (var i = 0; i < count; i++) {
        ret.push(++z)
        z %= 4;
    }
    return ret;
}

Upvotes: 1

Alberto De Caro
Alberto De Caro

Reputation: 5213

You can leverage on the map function and on the arithmetical module operator. Here follow a generalized version of your function:

function getModuleList(countFrom, count, mod) {
  var arr = [];
  for (var i = 0; i < count; i++){
    arr.push(i + countFrom);
  }

  return arr.map(function(num){ return num % mod || mod });

}

var quarterList = getModuleList(2, 9, 4);
console.log(quarterList);

Upvotes: 1

Related Questions