Yankee Doodle
Yankee Doodle, abbreviated as Yank, is a Lodash.pick inspired JavaScript package to pick object values from plain JavaScript objects. There’s zero dependencies to worry about, so naturally this package is really small at only around 9K minified. It’s safe to use in both browser and Node environments.
IE11 support is currently lacking due to some regular expressions that aren’t available in IE11 - stop using IE11!
Installing
$ npm i -S yankee-doodle
Getting Started
If you’re familiar with the pick/pickBy
methods in Lodash, then this
package should be easy to understand quickly. You can think of this package
like a superset to pick
from Lodash, with a feature rich schema syntax
that allows picking properties from an object in a much more declarative way.
Yanking properties from objects can be done by providing the data you want
to extract values from as the first parameter to the yank
method, and the
properties you wish to extract as either an array of schemas or as a series
of arguments.
The schemas you provide to Yank follow a similar syntax to JSON objects, only with the values stripped. There are additional syntaxes for manipulating which values are picked called filters.
All syntax and demo examples below use tests/data.json as the source of data for picking values from, as shown below.
{
"firstName": "John",
"lastName": "Doe",
"dateOfBirth": "1985-01-01",
"addressDetails": {
"address1": "10 Downing Street",
"address2": null,
"address3": null,
"city": "London",
"postcode": "SW1A 2AB"
},
"nested": {
"data": {
"items": {
"one": "one",
"two": "two",
"three": "three"
}
}
}
}
Syntax
Examples of schemas shown below are the strings you would provide as arguments to Yank, each followed by their resulting value. Each schema example is assumed to be the first and only schema parameter given to Yank.
Root property access
Schema
firstName,
lastName
Result
{
"firstName": "John",
"lastName": "Doe"
}
Nested properties
Schema
addressDetails: {
city
}
Result
{
"addressDetails": {
"city": "London"
}
}
Property path access
Schema
addressDetails.city,
nested.data.items: {
one,
two
}
Result
{
"city": "London",
"items": {
"one": "one",
"two": "two"
}
}
Filters
On each key within a schema, filters can be applied to manipulate how Yank
handles the value at that location. Filters are placed after the key, separated
by a pipe (|
), followed by parenthesis if the filter requires any arguments.
If no arguments are required, the parenthesis can be omitted. Multiple filters
can be applied simply by chaining additional filters separated by a pipe.
In addition, a macro flag can be applied to filters that support it by adding
an exclamation point (!
) to the end of the filter name.
Below is an example schema that makes use of filters.
Schema
firstName | as(first_name),
lastName | as(last_name),
doesNotExist | nullable,
alsoDoesNotExist | nullable!: {
thisWillBeNull,
soWillThis
},
dateOfBirth | as(dob) | nullable,
thisWontBeInTheResult
Result
{
"first_name": "John",
"last_name": "Doe",
"doesNotExist": null,
"alsoDoesNotExist": {
"thisWillBeNull": null,
"soWillThis": null
},
"dob": "1985-01-01"
}
Available filters
Name | Arguments | Macro | Description |
---|---|---|---|
as | (alias) | Renames the picked property | |
nullable | Sets child properties to nullable | Sets property to nullable | |
extract | Merges properties into the parent depth | ||
exec | (key, …args) | Executes a method at the current depth with additional arguments passed to the method |
Demo
Simply spread the property names into the yank
method and it will return
only those values from the given object.
Usage
yank(data, 'firstName', 'lastName')
Result
{
"firstName": "John",
"lastName": "Doe"
}
Alternatively, provide an array instead, or even a spread array of arrays, it’s all the same.
Usage
yank(data, ['firstName'], ['lastName'])
Result
{
"firstName": "John",
"lastName": "Doe"
}
All schemas are stripped of whitespace before parsing, so it’s easy and convenient to format them like you would for JSON.
Usage
yank(data, `
nested: {
data: {
items: {
one,
two
}
}
}
`)
Result
{
"nested": {
"data": {
"items": {
"one": "one",
"two": "two"
}
}
}
}
Have a nested object? Similar to JSON syntax, use {
and }
to yank child
properties. This can be as nested as you like.
Usage
yank(data, 'addressDetails: { address1, city }', 'firstName')
{
"addressDetails": {
"address1": "10 Downing Street",
"city": "London"
},
"firstName": "John"
}
Deeply nesting is possible as well.
Usage
yank(data, `
nested: {
data: {
items: {
one,
two
}
}
}
`)
{
"nested": {
"data": {
"items": {
"one": "one",
"two": "two"
}
}
}
}
Yanking properties that don’t exist will result in nothing happening for that particular key. The example below demonstrates that an empty object is returned because neither of the given properties exist on the original data object.
Usage
yank(data, 'emailAddress', 'phoneNumber')
Result
{}
Mixing existing properties with properties that don’t exist works too. The ones that don’t exist simply get ignored.
Usage
yank(data, [
`addressDetails: {
county
}`,
`addressDetails: {
city
}`,
'dateOfBirth'
])
Result
{
"addressDetails": {
"city": "London"
},
"dateOfBirth": "1985-01-01"
}
Tests
$ npm test
Acknowledgments
- Heavily inspired by Lodash.pick and supick.