davedub
davedub

Reputation: 94

array function that generates array with subset range of numbers

I am trying to create a function that builds an array up to a number set by the function parameter, with an if condition on being included based on whether the remainder is zero. The last number in the array should be no higher than the parameter. Here's what I came up with so far --

function justThreesUpTo(num) {  
var array = [];
array.length = num; 
for (i = 1; i < array.length; i++) {
  if(i % 3 === 0){
    array.push(i);
  }
    else i;
  }
  array.splice(0, num);
  return array;
}

When I console log this, with justThreesUpTo(20), I get --

// [ 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42 ]

I see the issue being setting the limiter at array.length, which maxes out the number of items that can be in the array, but I can't figure out what else to call to make sure the last number in the array goes no higher than the "num" parameter specified by the function call. Any ideas?

Upvotes: 2

Views: 75

Answers (6)

Ankit Agarwal
Ankit Agarwal

Reputation: 30729

Use while with i+=3; inside the while loop:

function justThreesUpTo(num) {  
  var array = [];
  var i = 0;
  while(i<num){
    array.push(i);
    i+=3;
  }
  return array;
}

console.log(justThreesUpTo(20));

Upvotes: 0

Ry-
Ry-

Reputation: 225291

Modifying an array while looping over it (or its indices, which is what you’re doing with i < array.length) is a recipe for confusion. Start with an empty array and compare with num instead:

function justThreesUpTo(num) {
    var array = [];

    for (var i = 1; i < num; i++) {
        if (i % 3 === 0) {
            array.push(i);
        }
    }

    return array;
}

Now you can optimize the check out of that entirely by moving up the appropriate amount each time.

function justThreesUpTo(num) {
    var array = [];

    for (var i = 3; i < num; i += 3) {
        array.push(i);
    }

    return array;
}

(In your original code, the entire first num holes created by array.length = num; are unused and get spliced off, and else i does nothing.)

Upvotes: 3

Mihai Alexandru-Ionut
Mihai Alexandru-Ionut

Reputation: 48437

You can use map method and spread syntax in order to write a clean solution.

function justThreesUpTo(num) {  
   return [ ...Array(Math.floor(num/3)).keys() ].map((_,i)=> (i+1) * 3);
}
console.log(justThreesUpTo(20));

Upvotes: 1

Nikhil Aggarwal
Nikhil Aggarwal

Reputation: 28475

You can try with a simple while loop

function justThreesUpTo(num) {  
   var array = [];
   var i = 0;

   while (i < num) {
     if(i % 3 === 0){
       array.push(i);
     }
     i++;
   }
   return array;
}

console.log(justThreesUpTo(20));

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 371233

Setting an array's length to something before the array is populated isn't a great idea - better to just iterate over the num itself. For example

for (var i = 1; i < num; i++) {
  // push to array if i % 3 === 0

Your else i won't do anything - you can just leave it off completely.

You could make your code a whole lot shorter and cleaner if you wanted:

function justThreesUpTo(num) {
  const length = Math.floor(num / 3);
  return Array.from({ length }, (_, i) => (i + 1) * 3);
}
console.log(justThreesUpTo(20));

Upvotes: 3

davedub
davedub

Reputation: 94

Hmm. Looks like it was a pretty simple solution. Changed the limiter from "array.length" to "num", and it worked fine.

function justThreesUpTo(num) {
var array = [];
array.length = num; 
for (i = 1; i < num; i++) {
  if(i % 3 === 0){
      array.push(i);
  }
  else i;
  }
  array.splice(0, num);
  return array;
}

Never mind!

Upvotes: 0

Related Questions