'How to get the first number in input values of range number or undefined

I want to get the first number value out of values with number or undefined range.

Obviously this fails for 0 which is falsy. What is the logical expression to return this?

    type Nomber = number | undefined

    function a_or_b_or_c_number_value_including_zero(a: Nomber, b: Nomber, c: Nomber) {
      return (a || b || c)
    }

    const test = (a: Nomber, b: Nomber, c: Nomber, expected: any) => {
      let got = a_or_b_or_c_number_value_including_zero(a, b, c)
      if (got !== expected) {
        console.log([a, b, c], 'fail', got, expected)
      }
    }


test(1, 2, 3, 1)
test(undefined, 1, 2, 1)
test(0, 1, 2, 0)
test(undefined, 0, 2, 0)


Solution 1:[1]

You can use the nullish coalescing operator to check it.

According to MDN:

The nullish coalescing operator (??) is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand.


This can be used in your code like below.

function a_or_b_or_c_number_value_including_zero(a: Nomber, b: Nomber, c: Nomber) {
  return (a ?? b ?? c); // Modified
}

This will make the code work the way you want, which will not make 0 equal to false.


This is how the code works.

Code Description
a ?? If a isn't null or undefined, use a.
b ?? c If b is null or undefined, use c, else, use b.

In conclusion, the nullish coalescing operator is a useful feature to not make 0 and "" equal to false (while || evaluates those values to false).

Solution 2:[2]

Use ?? instead of ||

function a_or_b_or_c_number_value_including_zero(a: Nomber, b: Nomber, c: Nomber) {
      return (a ?? b ?? c)
    }

Solution 3:[3]

You can use the the Nullish coalescing operator (??) to workaround the 0 failing for being falsy.

Solution 4:[4]

You can take advantage of rest parameters in order to write a function that accept any number of values and returns the first not undefined one:

type Nomber = number | undefined

function getFirstNumber(...values: Nomber[]) {
  for(let value of values){
    if (value !== undefined) return value;
  }
  return undefined;
}

You can see a demo here.

Solution 5:[5]

Use rest parameter spread with Array.find, along with a nullish coalescing operator that will return false if no match is found.

const test = (...args) => args.find(v => v !== undefined) ?? false

console.log(test(1, 2, 3, 1))
console.log(test(undefined, 1, 2, 1))
console.log(test(0, 1, 2, 0))
console.log(test(undefined, 0, 2, 0))
console.log(test())

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 eguneys
Solution 3 GMaiolo
Solution 4 Arnav Thorat
Solution 5