JS: How to use map function to replace a for-loop that loop x times?

Is there a workaround to use the Array map function to replace a for loop that loops 3 times?

for (let i = 0; i < 3, i++) {
  console.log(i);
}

One way I thought of is to use a dummy array:

[1, 2, 3].map((e, i) => {
  console.log(i);
}

But what if I need to loop 100 times? Looking for an elegant and more professional way of doing this.

Thanks!

Not really, because the point it to map over an existing array. So you could write a function that created an array from 0 to a given number, then map that, but it’s not very efficient. And it should be forEach, rather than map here – map maps values in an array to other values using the provided callback function, it’s not for side effects.

There’s nothing wrong with using a loop here

If you meant by elegant, shorter. You can try out the Array.forEach() loop. It is pretty easy to use. What it does is loop through every single item in your array. So ex:

let arr = [1, 3, 2, 5, 6, 3];

arr.forEach((num) => {
  console.log(num);
});

//the console will output as follows:
//1
//3
//2
//5
//6
//3

Then you can do something to it. Here’s an example:

let arr = [1, 5, 2, 7, 4, 6];

arr.forEach((num) => {
  if(num < 5) {
    console.log(num)
  }
});

//the console will output 
//1
//2
//4

In the context of creating a few repeated React components, how do I use for-loop to do so?

Option 1: This generates only 1 TodoItem component instead of 3.

export default function App()
{
  function generateToDo()
  {
      for (let i = 0; i < 3; i++) return <TodoItem />
  }
  return (
    <div>
      {
        generateToDo()
      }
    </div>
  );
}

Option 2: This generates an error when I use the for-loop in the curly braces.

export default function App()
{
  return (
    <div>
      {
        for (let i = 0; i < 3; i++) return <TodoItem />
      }
    </div>
  );
}

Map function works between the curly braces but I do not have an existing/meaningful array to loop through, except by creating a dummy array. For loop just can’t seem to work although it is my preferred method in this context.

Thanks!

You have it slightly backwards here: yes, map is the correct thing to use in this context, but you should already have an array of todos, you don’t need to create them. As you don’t have that array, yes, create a dummy array, but IRL you are going to have an array (or you have some functionality that adds new todos to an array, and you then map over that)

Thank you. Will think along those lines.

The [...range].forEach/map solution should only be used in a language that leverages the power of lazy evaluation, meaning that the range is not evaluated until the values (or indices) are actually needed. In a language that is mainly “eager” like JavaScript, if you do this you’d end up iterating over the whole array of indices TWICE.

First, the engine iterates from 0 to 99 when it reads something lke range(0, 100) (if it were to exist, a function that pushes numbers to an array from lower and upper limits A to B) for example, and then when it finishes parsing .forEach(runnable) or .map(mapper), it will iterate over the 100 values in the array making it do twice the work.

To solve this, you could create your own helper function that, instead of generating an array whose sole purpose is to create a range for you to iterate, uses a for loop behind the courtain.

/**
 * Executes a function that receives an index number
 * N times, and produces a value. The results are
 * collected inside the returned array. The lower and
 * upper limits determine the amount of elements
 * to produce and the index sent to the producer.
 * @param {number} a - Lower range limit.
 * @param {number} b - Upper range limit.
 * @param {function(i: number): T} f - Producer.
 * @return T[] - Array that contains all the
 * returned values from the executions of f.
 */
function doRange<T>(
  a: number,
  b: number,
  f: (i: number) => T
): T[] {
  if (a > b) {
    [a, b] = [b, a];
  }

  const result: T[] = Array(b - a);
  
  for (let i = 0; i + a <= b; i++) {
    result[i] = f(i + a);
  }

  return result;
}

const identity = <T>(x: T): T => x;
const range = (a: number, b: number) =>
  doRange(a, b, identity);

range(7, 4);
//> [4, 5, 6, 7]
doRange(0, 2, i => <li key={i}>Item #{i}</li>);
//> <li>Item #0</li>
//> <li>Item #1</li>
//> <li>Item #2</li>

You can see it in action here without the typescript syntax:

I think everyone missed his question.

The answer is:

const range = (s, e) => Array.from({length: (e - s)}, (_, i) => i + s);