1

So I have a string that I want to draw onto a HTML5 Canvas using javascript. I have got separate functions that will draw each character of the alphabet.

I have used a for loop to iterate through the characters in the string.

let theText = "String"

for (let i = 0; i < theText.length; i++) {
  theText[i];
}

I also have functions for each character in the alphabet

function draw_A() {
  //code that draws A
}

... a through to x

function draw_X() {
  //code that draws X
}

Currently my solution to drawing the characters is

for (let i = 0; i < theText.length; i++) {
  c = theText[i];

  if (c == "A") {
    draw_A();
  }

  ... a through to x

  else if (c == "X") {
    draw_X();
  }
}

I know this method is inefficient and I have also tried using case, however, that is just a simplified version of what I'm doing already.

I know that if you want to insert a variable into a string in javascript you can use the ${} characters inside of `` to do this. The below code will insert the variable 'username' into a string.

let myString = `Hello ${username}, welcome to this script`;

Is there a similar way to do this with functions. I don't want to have to write 26 if or case statements to carry out something that I know should be much simplier

5
  • You should put your functions in an array (or object). Commented Jun 1, 2018 at 15:55
  • Why do you need separate functions for each letter? Is the code that prints each letter that complex? Could you not have one function that accepts a letter as an argument and then draws it? Commented Jun 1, 2018 at 16:03
  • @skyline3000 The code used to draw each letter is very complicated, the letter is not actually drawn with a drawText command, it is drawn bu individual rectangles and arcs. I have basically deigned my own type set for each letter and these need to be separate functions because of this Commented Jun 10, 2018 at 21:04
  • @SLaks I have already tried putting these into an array however, that is complicated and rather resource intensive. I was looking for something where I did not need a loop or lookup as this would be quite intensive Commented Jun 10, 2018 at 21:06
  • @CakeHook: Lookups are actually quite fast. Commented Jun 10, 2018 at 23:34

2 Answers 2

2

Just create a lookup object:

const lookup = {
 a: draw_A,
 /*...*/
 x: draw_X
};

And then you can just do

lookup["a"]()

Currently you could do it a bit more hacky (/ugly) without a lookup object:

window["draw_" + "a"]()
Sign up to request clarification or add additional context in comments.

4 Comments

Your answer was great until you proposed the horrible alternative at the end.
Hacky? Ugly? No, it's just the wrong thing to do.
Could I replace "a" with ${character} so that it would run the correct function for a character in a string? Forgive me for not understanding, I am self taught :) but why is the last solution so bad? Also where does window come from in window["draw_" + "a"]() @Bergi @torazaburo @jonas-w
@CakeHook Sure you can do const character = "a"; lookup[character]();. The latter solution is so bad because it requires your variables to be global (which is bad)
1

You can use an object literal that matches the character to the function

let functionHash = {
  a : draw_A,
  b : draw_b
  //etc.....
}

functionHash['a'](); //Calls draw a

This will consume a fixed amount of memory. Another approach that doesn't use a data structure would be a switch statement. As long as the size of your incoming characters is constant.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.