Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I assign a conditional variable without mutation?

I am adhering to strict functional programming principles with no mutation.

How can I write something like the below code in a way that doesn't mutate the greeting variable, and without returning it within each if block?

const greet = (name, time) => { 
  let greeting = 'Morning';

  if(time >= 12) {
    greeting = 'Afternoon';
  }
  if(time >= 17) {
    greeting = 'Evening';
  }

  return `Good ${greeting} ${name}!`;
};

If it was just two conditions I would do the following, but it won't work when there are 3 conditions:

const greeting = time > 12 ? 'Afternoon' : 'Morning'
like image 348
Jim Moody Avatar asked Jul 26 '17 17:07

Jim Moody


People also ask

How do you set a variable based on a condition?

The conditional ternary operator in JavaScript assigns a value to a variable based on some condition and is the only JavaScript operator that takes three operands. result = 'somethingelse'; The ternary operator shortens this if/else statement into a single statement: result = (condition) ?

What is variable mutation in JavaScript?

A value is said to be mutable if it can be changed. That's all there is to it: a mutation is the act of changing the properties of a value. All primitive value in JavaScript are immutable: you can't change their properties — ever.


2 Answers

Ternary expressions can be made up other ternary expressions – allowing us to sequence logical choices

const greeting = time > 12 ? (time > 17 ? 'Evening' : 'Afternoon') : 'Morning'

However, I think it's the variable that makes the variable a variable...


You have two concerns though, and it it will benefit you to separate them

  1. determining the day period from the hour
  2. assembling the greeting string

By doing this, you avoid

  1. mutation (local reassignment of greeting)
  2. single-branch if statements
  3. imperative-style statements altogether (ie let, if, return, x = ...)

The result is two pure (referentially transparent) functions written using expressions – there is no assignment (or reassignment), and there are no side-effects.

const timeToPeriod = time =>
  time >= 17
    ? 'Evening'
    : time >= 12
      ? 'Afternoon'
      : 'Morning'

const greet = (name, time) =>
  `Good ${timeToPeriod(time)} ${name} !`
  
console.log(greet('Jonas', 9))  // Good Morning Jonas !
console.log(greet('Jonas', 13)) // Good Afternoon Jonas !
console.log(greet('Jonas', 22)) // Good Evening Jonas !
like image 85
Jonas Wilms Avatar answered Oct 14 '22 08:10

Jonas Wilms


const greeting = [
  'Morning', 'Morning', 'Morning', 'Morning', 'Morning', 'Morning', 'Morning', 
  'Morning', 'Morning', 'Morning', 'Morning', 'Morning',
  'Afternoon', 'Afternoon', 'Afternoon', 'Afternoon', 'Afternoon',
  'Evening', 'Evening', 'Evening', 'Evening', 'Evening', 'Evening', 'Evening'
]

return `Good ${greeting[time]} ${name}!`

This technically gives you the flexibility to add more times of day in the future, such as adding 'Noon' on the 12th hour. Additionally, it makes localization easier for similar reasons; Some locales may have a Noon others may not.

This was originally a joke ;)

like image 29
Soviut Avatar answered Oct 14 '22 10:10

Soviut