Table of Contents
Issue
I am currently starting studying JS and I need to do the follow exercise with switch statement.
function colorMix (color1, color2){
if ((color1 === 'red' && color2 === 'blue') || (color1 === 'blue' && color2 === 'red')){
return 'violet';
} else if ((color1 === 'red' && color2 === 'yellow') || (color1 === 'yellow' && color2 === 'red')){
return 'orange';
} else if ((color1 === 'blue' && color2 === 'yellow') || (color1 === 'yellow' && color2 === 'blue')){
return 'green';
} else {
return 'need to mix two diferent colours'
}
}
let myColor = colorMix('blue', 'blue');
console.log(`The color created is: ${ myColor}`);
that is what I got so far but it’s not working:
let color1 = '';
let color2 = '';
let firstColour = ((color1 === 'red' && color2 === 'blue') || (color1 === 'blue' && color2 === 'red'))
let secondColour = ((color1 === 'red' && color2 === 'yellow') || (color1 === 'yellow' && color2 === 'red'))
let thirdColour = ((color1 === 'blue' && color2 === 'yellow') || (color1 === 'yellow' && color2 === 'blue'))
function colorMix (color1, color2){
switch (color1, color2){
case 'firstColour':
return 'violet';
break;
case 'secondColour':
return 'orange';
break;
case 'thirdColour':
return 'green';
default:
return 'error';
}
}
let myColour = colorMix('red', 'blue');
console.log(`Colour created is ${myColour}`)
I don’t know how to make the switch statement to recognize the colors I introduce. Any thoughts? thanks!!!
Solution
The expression (color1, color2)
evaluates to color2
because the comma is an operator here. So that is not useful for a switch
statement.
One way to make it work, is to translate color strings to color numbers, in such a way that the principle colors (red, yellow, and blue) are powers of 2. If they are added together (or better OR’d together), the other color numbers are found.
Here is how that could be done:
const colorNames = ["none", "red", "yellow", "orange", "blue", "violet", "green", "black"];
const colorNums = Object.fromEntries(colorNames.map((name, i) => [name, i]));
const colorMix = (color1, color2) => colorNames[colorNums[color1] | colorNums[color2]];
console.log(colorMix("blue", "red")); // violet
// Order does not matter
console.log(colorMix("red", "blue")); // violet
// Mixing a color with itself does not change it
console.log(colorMix("orange", "orange")); // orange
// Can mix an already mixed color again
console.log(colorMix("violet", "yellow")); // black
Explanation
const colorNames = ["none", "red", "yellow", "orange", "blue", "violet", "green", "black"];
Here we create an array of color names. The index at which a name occurs in this array, is its unique identifier. The principle colors are on indices that are powers of two: 1, 2 and 4. If we would write the indices as binary numbers, the above array looks like this:
index in binary | color name |
---|---|
000 | none |
001 | red |
010 | yellow |
011 | orange |
100 | blue |
101 | violet |
110 | green |
111 | black |
This array can be used to give the color name that corresponds to an index. Notice how "orange" (011) combines the binary bits of "red" (001) and "yellow" (010), taking a "1" when either of the mixed colors has a "1" in the same position of the binary representation.
The following statement creates the reverse mapping (from name to index):
const colorNums = Object.fromEntries(colorNames.map((name, i) => [name, i]));
The .map()
creates pairs of name and index (the above table but with the columns swapped). Object.fromEntries
uses this information to create a plain object:
{
none: 0,
red: 1,
yellow: 2,
orange: 3,
blue: 4,
violet: 5,
green: 6,
black: 7
}
With these two conversion objects we can now make a nice color mixer function:
const colorMix = (color1, color2) => colorNames[colorNums[color1] | colorNums[color2]];
The two colors are each converted to their number using colorNums
.
These two numbers are combined using the binary OR operator (|
). This will give the number of the color we want to get.
Finally that value is translated back to a color name, using the colorNames
array.
The rest of the script illustrates how the function can be called:
- The order of the arguments does not matter
- When both input colors are the same, the behaviour is different from what you did: the color is just returned unchanged, reasoning that mixing a color with itself does not change the color.
- Already mixed colors can be mixed again (This is of course a simplification of reality where mixing colors is influenced by the amount of paint that is mixed with another color. The relative amounts influence the outcome).
Answered By – trincot
Answer Checked By – Mary Flores (BugsFixing Volunteer)