3

I would like to create a function returning an array of functions. When any function from the array is called, the result must be the index of this function in the array. The task and challenge are to create this function without for-loops. I was moving this way, however, the code did not work as I expected:

const createArrayOfFunctions = number => {

  const functionsArray = new Array(number).fill();

  return functionsArray.map(element => function() {

    return functionsArray.indexOf(element);

  });

};

I expected:

const testArray = createArrayOfFunctions(7);
testArray[2](); // 2;

Is there any way to have the goal achieved without using for-loops. I need it for a study project.

  • Do a `console.log(functionsArray)`. You'll notice that it consists of only `undefined` values. Doing `functionsArray.indexOf(element)` will always find the `undefined` at index 0. – Bergi Jan 09 '22 at 16:21
  • You'll want to check the [docs for the `map` method](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map#parameters) again. No need to use `indexOf` to find out on which index the callback is invoked! – Bergi Jan 09 '22 at 16:23

4 Answers4

1

You can achieve your goal by using Array.from like this:

const createArrayOfFunctions = length => Array.from({length}, (v, i)=> ()=> i);

const arrayOfFunctions = createArrayOfFunctions(10);
console.log(arrayOfFunctions[0]())
console.log(arrayOfFunctions[9]()) // last item would be 9
Saeed Shamloo
  • 6,199
  • 1
  • 7
  • 18
1

First, you use new Array(number).fill(), which makes an array of undefined. So, when you call testArray(2)(), your element inside your return function is also undefined. then you tried to find the index of undefined, it returns 0. The reason it returns 0 is because your functionsArray is an array of 7 undefined in your case, then Array.indexOf will return the first match, and since functionArray[0] is undefined, that's why it always return 0 no matter which function you call within your functionArray. Make sense?

I made a little change of your code, try this. It should work as you would expect. I didn't use Array.indexOf or any other array methods just because you only want the index, why not consider using the index instead?

If you insist that you want to use Array.indexOf to solve your problem, you will have to use a forloop inside createArrayOfFunctions to create your functionsArray with different elements(e.g. 0,1,2,3,4...7), because new Array(number).fill() creates array of undefined, and even if you do Array(number).fill(number), you still just create an array of 7s in your case, so that is exactly the same thing as an array of 7 undefined in your case. So your method won't work. Since you mentioned no forloop, that's why I provided the method using index as described above.

Also I would recommend you to add some logic or create a separate function to make sure no one can call the testArray out of bound, for example, if you create 7 array functions, you don't want people to be able to call testArray[8]. I hope this helps. let me know if you have any confusion.

const createArrayOfFunctions = (number) => {
  functionsArray = new Array(number).fill(0);
  return functionsArray.map((element, index) => {
    return () => {          
      return index;
    };
  });
};

const testArray = createArrayOfFunctions(7);
console.log(testArray[2]()); // 2;
console.log(testArray[3]()); // 2;
console.log(testArray[1]()); // 2;
  • Thank you. I loved your solution at first place, however, I also did not understand the sense of indexNew. I went on to experiment with your code, and achieved the same result with just an index. But the direction you took was exactly what I needed! Thank you, and good job! – Yevhen Zhemchuzhnykov Jan 09 '22 at 17:55
  • On my bad, I actually only updated the explanation, earlier the explanation included that index and newIndex part, but forgot to update the code. I just updated it. thanks. – David Liang Jan 09 '22 at 18:42
-1

First of all, I suggest you change new Array().fill() to just [].

We are able to recreate a for loop using a while loop.

let x = 0
while (x < 5) {
console.log(`five times`)
x++
}

Therefore, I suggest you do this:

function createarray() {
let arrayfunc = []
let i = 0
while(i<10) {arrayfunc.push(new Function(‘console.log(\‘ + i + \‘)\‘))}
return arrayfunc
}
Hermanboxcar
  • 418
  • 1
  • 13
  • Don't use `eval` here – Bergi Jan 09 '22 at 16:22
  • Absolutely. eval is evil. it is evil because people can hack your site if you use eval. Function class can only access globals while eval can access all the variables and stuff in your site. – Hermanboxcar Jan 10 '22 at 23:48
  • Access to globals will give a hacker access to all the stuff in your site, using `Function` with arbitrary code is just as evil. But that's not what I mean, there is no security issue here, it's just a [bad practice to eval source strings](https://stackoverflow.com/a/86580/1048572) when all you need is a closure. – Bergi Jan 11 '22 at 01:02
-2

Assign default value '0' to Array.fill() method.

const createArrayOfFunctions = (len) => {
  const functionsArray = Array(len).fill(0);
  return functionsArray.map((ele, index) => () => index );
};

const testArray = createArrayOfFunctions(7);
console.log(testArray[0]());
console.log(testArray[6]());
Rahul Kumar
  • 3,009
  • 2
  • 16
  • 22