Today I want to share a pretty cool one-liner that makes your navigation in complex objects a breeze.. In just one minute 🤯
Let's get straight to the point.
const navigator = (obj, path) => path.reduce((a, b) => a && a[b], obj);
Given an object and an array representing all the properties (in descending order) from parent to the target property, we can navigate to our target value.
The native Array.prototype.reduce
method is helping us achieve just that.
You can get familiar with reduce
here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
We are providing our complex object as the initial value to our reduce
method. And we are also providing a function that handles the reduction of our initial value.
We can then use the navigator
function like that:
// Test object
const test = {
a: {
b: {
c: 'test',
},
},
};
navigator(test, ['a', 'b', 'c']); // 'test'
The basic flow
Let's break it down what's happening in here:
➡ On first execution a
, the accumulator, will have value obj
.
➡ If a[b]
exists, on the next iteration, a
will be equal to a[b]
.
➡ If a[b]
is undefined, then a
is our target value.
NOTE: Using the logical AND operator (&&), if both values are truthy, the second value will be returned.
Looking for a more convenient syntax
The array notation to describe a nested path is not so handy.
But fortunately, we can upgrade it to a more convenient dot notation syntax pretty easily.
// Splitting dot notation path => resulting in the array we need.
const navigator = (obj, path) => path.split('.').reduce((a, b) => a && a[b], obj);
Then we can finally use it like the following:
const test = {
a: {
b: {
c: 'test',
},
},
};
// 🎉🎉🎉🎉
navigator(test, 'a.b.c'); // 'test'
We have now the power to navigate very deeply nested properties with only one line of js 🎉🎉
Top comments (1)
Great one-line helper!
I think the post misses the the motivation behind
navigator
function. Indeed, why usenavigator(test, 'a.b.c')
instead of shorttest.a.b.c
?This
navigator
function helps to avoid runtime errors when trying to read properties fromnull
orundefined
.test.z.x
will throw, butnavigator(test, 'z.x')
will returnundefined
.This is such a common problem, so TC39 proposes optional chaining with syntax
test?.a?.b?.c
which is currently in stage2.