Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a better(cleaner) way to write this JS code using ternary operators(without repeating code)?

So I'm writing a simple React.js app and just have a question about setting state, can this be done any cleaner?

const enemy = this.state.enemy;
        if (this.state.isRock) {
            enemy === "rock"
                ? this.setState({ result: "Draw!" })
                : enemy === "paper"
                ? this.setState({ result: "You lose!" })
                : enemy === "scissors"
                ? this.setState({ result: "You win!" })
                : this.setState({ result: null });
        } else if (this.state.isPaper) {
            enemy === "rock"
                ? this.setState({ result: "You win!" })
                : enemy === "paper"
                ? this.setState({ result: "Draw!" })
                : enemy === "scissors"
                ? this.setState({ result: "You lose!" })
                : this.setState({ result: null });
        } else if (this.state.isScissors) {
            enemy === "rock"
                ? this.setState({ result: "You lose!" })
                : enemy === "paper"
                ? this.setState({ result: "You win!" })
                : enemy === "scissors"
                ? this.setState({ result: "Draw!" })
                : this.setState({ result: null });
        }
like image 207
Nikola Pavlov Avatar asked Jan 26 '23 13:01

Nikola Pavlov


2 Answers

Considering there are only three possible states (win, lose, draw), we only need to check for two of them. Draw is easy to check for, so we only need the state of win or lose. Here is an example:

const enemy = this.state.enemy;
let wins = {
    "rock"     : "scissors",
    "paper"    : "rock" ,
    "scissors" : "paper",
}
let play = (this.state.isRock ? "rock" : (
  this.state.isPaper ? "paper" : (
    this.state.isScissors ? "scissors" : null
    )
  )
)

if (!wins[play]) {
    this.setState({ result: null })
} else if (enemy == play) {
    this.setState({ result: "Draw!" })
} else if (wins[play] == enemy) {
    this.setState({ result: "You win!" })
} else {
    this.setState({ result: "You lose!" })
}
like image 136
cegfault Avatar answered Jan 29 '23 14:01

cegfault


You can have the conditions as part of the map as the condition never changes and set the state.

const condition = {
  "rock": {
    "paper": "You lose!",
    "sccissors": "You win!",
    "rock": "Draw!"
  },
  "paper": {
    "rock": "You win!",
    "sccissors": "You lose!",
    "paper": "Draw!"
  },
  "sccissors": {
    "rock": "You lose!",
    "paper": "You win!",
    "sccissors": "Draw!"
  }
};

function getResult(enemy, isRock, isScissors, isPaper) {
  let result = null;
  
  if (isRock) {
    result = condition['rock'][enemy];
  } else if (isPaper) {
    result = condition['paper'][enemy];
  } else if (isScissors) {
    result = condition['scissors'][enemy];
  }
  
  return result;
}

const {
  isRock, 
  isScissors,
  isPaper,
  enemy
} = this.state;


this.setState({
  result: getResult(enemy, isRock, isScissors, isPaper)
})
like image 24
Sushanth -- Avatar answered Jan 29 '23 14:01

Sushanth --