first non-null/undefined argument in JavaScript
The process of finding the first argument that is not null or undefined in JavaScript is known as coalescing.
We need to implement a function coalesce() that takes multiple arguments and returns the first non-null and non-undefined value.
Example:
Input: coalesce(null, undefined, "First", 1, 2, 3, null)
Output: "First"
Explanation: The first non-null value argument is "First".Input: coalesce(undefined, null, null, 100, "Hello")
Output: 100
Explanation: The first non-null value argument is 100.Input: coalesce(null, null, null, null)
Output: undefined
Explanation: All values are null, so function returned undefined.
[Approach – 1] Using Loop Traversal – O(N) Time and O(1) Space
We can implement coalescing in pre-ES6 JavaScript by looping through the arguments and checking which of the arguments is equal to NULL. We then return the argument that is not NULL immediately.
function coalesce() {
// Loop through all the arguments passed to the function
for (let i = 0; i < arguments.length; i++) {
// Return the first argument that is not null or undefined
if (arguments[i] != null) {
return arguments[i];
}
}
}
// Driver Code
console.log(coalesce(null, undefined, "First", 1, 2, 3, null));
Output
First
[Approach – 2] Using ES6 find() with Rest Parameters – O(N) Time and O(N) Space
We can use the ES6 alternative to the above method to achieve a similar effect. Using Rest Parameters in ES6, we collect all the arguments in the args iterable. We pass a arrow function as a callback to the find method, that iterates over each element of args. We use a throwaway variable in the _ identifier as the element identifier in the callback to the find method.
Finally, we use the includes() method to check if the element identified by _ in the callback belongs to either null or undefined. The first element that does not meet the test is our output.
Example:
const coalesceES6 = (...args) =>
// Use Array.find() to get the first element not equal to null or undefined
args.find(_ => ![null, undefined].includes(_));
// Driver Code
console.log(coalesceES6(null, undefined, "Value One", 1, 2, 3, null));
Output
Value One
Use Cases of Coalescing
Now that we have seen how to implement Coalesce, let's discuss what are some of its use cases.
Use Case 1: Filling up for null/undefined values in an array of objects
Example: In a product catalog with many listings, each product has a description and a summary. When the summary is missing, coalescing can be used to fall back to a truncated version of the description.
coalesceES6 = (...args) => args.find(val => ![null, undefined].includes(val));
// Display product details with a fallback summary
function displayProdCat(products) {
for (const product of products) {
console.log(`ID = ${product.id}`);
console.log(`Description = ${product.desc}`);
// Use product summary if available, otherwise derive from description
const summary = coalesceES6(product.summ, product.desc.slice(0, 50) + "...");
console.log(`Summary = ${summary}`);
}
}
// Product data
const products = [
{
id: 1,
desc: "Best in class toaster with 140W power.",
summ: "Get world class breakfasts",
},
{
id: 2,
desc: "Massager with Li-Ion battery lasting 8 hours.",
summ: "Warm comfort for your back",
}
];
// Display all product details
displayProdCat(products);
Output
ID = 1 Description = Best in class toaster with 140W power and compact design. Summary = Get world class breakfasts ID = 2 Description = Massager with Li-Ion battery lasting 8 hours for pain relief. S...
Use Case 2: Filling up values in case of missing numeric values in expressions to perform computations
Example: Given an array of monthly incomes with missing values, calculate the annual income by substituting a default value of 1000 wherever data is missing.
incomeFigures = {
default: 1000,
monthWise: [1200, , 600, 2100, , 329, 1490, , 780, 980, , 1210],
};
coalesceES6 = (...args) =>
args.find((_) => ![null, undefined].includes(_));
function yearlyIncome(incomeFig) {
// use coalesce to replace missing with default
return incomeFig.monthWise.reduce(
(total, inc) =>
total + coalesceES6(inc, incomeFig.default), 0);
}
console.log(
`Yearly income equals ${yearlyIncome(incomeFigures)}`
);
Output:
Yearly income equals 8689