README
smart-mole
Introduction
JavaScript library to dig nested object returned from api.
If api endpoint returns,
{
animal: {
mammal: {
moles: [
{
name: 'parent1',
children: [{ name: 'child1-1' }, { name: 'child1-2' }]
},
{
name: 'parent2',
children: [{ name: 'child2-1' }, { name: 'child2-2' }]
}
]
}
}
}
and you want to get ['child1-2', 'child1-2', 'child2-1', 'child2-2']
, with pure javascript,
object.animal.mammal.moles.map(mole => mole.children.name) // => ['child1-2', 'child1-2', 'child2-1', 'child2-2']
This code does not show the composition of the object, so it is difficult to understand how is the object
.
On the other hand, with this library,
import { dig, $target, $array } from 'smart-mole'
dig(obj, {
animal: {
mammal: {
moles: $array({
children: $array({ name: $target })
})
}
}
})
// => ['child1-2', 'child1-2', 'child2-1', 'child2-2']
Quick start
Install
npm i smart-mole
or
yarn add smart-mole
How to use
import { dig } from smart-mole
dig(<target_object>, <target_map>, <target_marker>)
argument|description
--|--
target_object|object or array you want to dig
target_map|object or array presenting target location, by marking target with target_marker
target_marker|optional, default is $target
which is a constant of **target**
Note that target_marker should NOT be included in any keys of <target_object>. if included, it will cause a bug. Bad example:
const object = { '**target**': { bar: 1 } }
dig(object, { '**target**': { bar: $target } }
You should change target_marker like this.
dig(object, { '*foo': { bar: '***' } }, '***')
Algorithm
- Convert target_map to JSON string.
JSON.stringify(target_map)
// => {"animal":{"mammal":{"moles":[{"name":"_"},{"name":"*"}]}}}
- From the result of 1, search a object or array that includes target_marker.
{"animal":{"mammal":{"moles":[{"name":"_"},{"name":"*"}]}}}
// ^^^^^^^^^^^^
=> {"name":"*"}
- From the result of 2. get the key and memorize it.
{"name":"*"}
=> 'name'
// keys <- 'name'
- replace the result of 2. by target_marker.
{"animal":{"mammal":{"moles":[{"name":"_"},{"name":"*"}]}}}
// ^^^^^^^^^^^^
// replace => {"animal":{"mammal":{"moles":[{"name":"_"},"*"]}}}
- From the result of 4, search a object or array that includes target_marker(like 2.)
{"animal":{"mammal":{"moles":[{"name":"_"},"*"]}}}
// ^^^^^^^^^^^^^^^^^^
- get the key(or index) and memorize it.
[{"name":"_"},"*"]
=> 1 (index)
// keys <- 1
// keys: ['name', 1]
- repeat until the result of replacement is same as target_marker.
keys: ['name', 1, 'moles', 'mammal', 'animal']
- Using keys, dig a target object
let value = object
for (const key of keys.reverse()) {
value = value[key]
}
value // => 'Don Resetti' (same as object.animal.mammal.moles[1].name)
Caution
You should just use Destructuring assignment in some case.
/*
object is {
animal: {
mamal: {
moles: [
{ name: 'Mr. Resetti' },
{ name: 'Don Resetti' }
]
}
}
}
*/
// you can get 'Don Resetti' by the folloing method
const { animal: { mamal: { moles: [, { name }] } } } = object
console.log(mole) // => 'Don Resetti'