I really like using Ruby's Array#dig
and Hash#dig
operator (introduced in Ruby 2.3) to quickly and safely access deeply nested structures
I would love to see different versions of it in other languages so I can use them more too!
Here's how dig works:
Assuming we have an orders
array that looks like this.
orders = [
{
id: 1,
customer: {
name: "Customer 1",
phone: "1234"
}
},
{
id: 2
},
# ...
]
We can easily navigate through this structure with dig
like so
orders.dig(0, :customer, :phone) #=> "1234"
We can also not worry about any of the "in-between" objects not existing, as it will return nil as soon it finds something that doesn't exist.
orders.dig(1, :customer, :phone) #=> nil
It returns nil
the moment it finds that customer
doesn't exist, and it makes me avoid checking if keys exist every time I want to access a nested object.
What are some cool ways to access nested data like this in other languages? I ask because I want to learn and because I probably do it in overly-convoluted ways at the moment.
Thanks for reading!
Latest comments (14)
Now available for Javascript:
npmjs.com/package/jsdig
PHP7 introduced the null coalesce operator (
??
) which will suppress errors for the missing intermediate keys. So, this will work without errors/warnings:The Laravel framework in PHP also has array helpers which allow you to access values using "dot" notation:
You can pass a third value to use as the default if it doesn't exist, but the default is
null
without it.This helper function is a shortcut to access the
Arr::get()
method mentioned by Suhayb Alghutaymil.In Elixir use Kernel.get_in/2 for maps
Thank you for sharing everyone! I learned a lot!
Haskell and other functional languages have Lenses, which are roughly equivalent to focusing on a value or path and either getting or setting it. Imagine
dig
with a relatedbury
function and you get close.I'd mentioned it in this particular Storybook post in Part Four, though it may make more sense to start at Part One for continuity
I'm a heavy user of Ramda's #path method in JavaScript / Node
In Java (version 8 and onward) this can be done using Optional
C# 6.0 and onwards gives you the Null Propagating Operator MSDN Guide — like many of the other languages here, you would use it something like:
This can be combined with the null coalescing operator, to give a default value:
For Python, glom is a great package for this sort of nested data access. The happy path from the intro docs looks like this:
That
'a.b.c'
bit is a simple glom specifier, but it can get much wilder! Glom provides more advanced specifiers for features like:And you can always plug in your own code or extend glom even further. Simple to get started, but a long fun road to travel from there!
Kotlin
See this runnable snippet pl.kotl.in/1aOqY8rQu
In Laravel you could use this with Arr::get helper method.
I'm currently doing Rust, and I have a little trouble answering this question.
A couple points:
dig
built-in.nil
/null
/whatever in Rust - if it's aString
, it's there, no strings attached (pun intended).Option
enum, which can be eitherSome(value)
orNone
(the concept is not new - Haskell hasMaybe
, and languages like Swift or Kotlin have nullable types)Options
.I came up with this:
Looks a bit funky, but does the job:
EDIT: I completely forgot about a cool language feature in Rust -
?
operator.Synopsis:
Result<T, E>
is very similar toOption<T>
, but it instead can be eitherOk(T)
(all good,T
is the value) orErr(E)
(something went wrong,E
is the error type -String
for a message, etc.)result?
basically means .if it's Ok, get the inner value and continue execution. If it's an Err,return
it".It allows for code like this:
It's known as optional chaining / null propagation.
In Javascript it's described as ECMAScript proposal
instead of writing:
it could be like:
For now, there are libraries like lodash/get, where we can use function: