パッケージの詳細

selectn

wilmoore371.5kMIT1.3.0

Curried property accessor function that resolves deeply-nested object properties via dot/bracket-notation string path while mitigating TypeErrors via friendly and composable API.

Mitigate TypeError, TypeError, TypeErrors, access

readme

selectn

Curried property accessor function that resolves deeply-nested object properties via dot/bracket-notation string path while mitigating TypeErrors via friendly and composable API.

Build Status Code Climate JavaScript Style Guide types npm NPM downloads

yarn add selectn

or

npm install selectn --save

or

<script src="https://unpkg.com/selectn/selectn.min.js"></script>

You may also install selectn via Bower or jspm.

Overview

allows you to refactor this:
person && person.info && person.info.name && person.info.name.full
into:
selectn('info.name.full', person)
or refactor this:
contacts.map(function (contact) {
  return contact && contact.addresses && contact.addresses[0]
})
into:
contacts.map(selectn('addresses[0]')))

Demo

npm

Features

  • Mitigate boilerplate guards like if (obj && obj.a && obj.a.b && obj.a.b.c).
  • Mitigate TypeError Cannot read property '...' of undefined.
  • Multiple levels of array nesting: 'group[0].section.a.seat[3]'.
  • Dashed key access: 'stats.temperature-today'.
  • When the value at the given path is a function, it is invoked and the functions returned value is returned.
  • selectn is auto-curried so partial application is automatic when you omit the second argument.
  • selectn uses Haskell style parameter order (AKA: data-last) which enables pointfree style programming.
  • Functions returned by selectn are higher-order property accessors which can be passed to other higher-order functions like map or filter.
  • Compatible with modern and legacy browsers, Node/CommonJS, and AMD.

Non-Features

  • No eval or Function (see: eval in disguise).
  • No typeof since, typeof is not a real solution to this problem but can appear to be due to the way the global scope is implied.

Usage example(s)

property accessor as predicate

Avoid annoying Cannot read property '...' of undefined TypeError without writing boilerplate anonymous functions or guards.

var selectn = require('selectn')
var language = [
  { strings: { en: { name: 'english' } }},
  { strings: { es: { name: 'spanish' } }},
  { strings: { km: { name: 'khmer'   } }},
  { strings: { es: { name: 'spanish' } }},
  { nodatas: {}}
]

var spanish = selectn('strings.es')
//=> [Function]

language.filter(spanish).length
//=> 2

point-free property accessor

Access deeply nested properties (including dashed properties) using point-free style.

var selectn = require('selectn')
var data = {
  client: {
    message: { 'message-id': 'd50afb80-a6be-11e2-9e96-0800200c9a66' }
  }
}

var getId = selectn('client.message.message-id')
//=> [Function]

Promise.resolve(data).then(getId)
//=> 'd50afb80-a6be-11e2-9e96-0800200c9a66'

property accessor for functor

Avoid wrapping property accessors in anonymous functions.

var selectn = require('selectn')
var contacts = [
  { addresses: [ '123 Main St, Broomfield, CO 80020', '123 Main St, Denver, CO 80202' ] },
  { addresses: [ '123 Main St, Kirkland, IL 60146' ] },
  { phones: [] },
]

var primaryAddress = selectn('addresses[0]')
//=> [Function]

contacts.map(primaryAddress)
//=> [ '123 Main St, Broomfield, CO 80020', '123 Main St, Kirkland, IL 60146', undefined ]

support for keys containing .

Pass an array as path instead of a string.

var selectn = require('selectn')
var data = {
  client: {
    'message.id': 'd50afb80-a6be-11e2-9e96-0800200c9a66'
  }
}

selectn(['client', 'message.id'], data)
//=> 'd50afb80-a6be-11e2-9e96-0800200c9a66'

value at path is a function

Avoid var fn = data.may.be.a.fn; if (typeof fn === 'function') fn().

var selectn = require('selectn')
function hi () { return 'hi' }
var data = { may: { be: { a: { fn: hi } } } }

selectn('may.be.a.fn', data)
//=> 'hi'

API (partial application)

selectn(String|Array)

arguments
  • path (String|Array) Dot/bracket-notation string path or array.
returns
  • (Function) Unary function accepting the object to access.

API (full application)

selectn(String|Array, Object)

arguments
  • path (String|Array) Dot/bracket-notation string path or array.
  • object (String|Array) Object to access.
returns
  • (*|undefined) Value at path if path exists or undefined if path does not exist.

Other Languages

selectn has inspired ports to other languages:

Language Project
Python selectn

Related

Other JS packages whose friendly API is driven by selectn:

Inspiration

JS packages that have inspired selectn:

Alternatives

Alternative packages you might like instead of selectn:

Licenses

LICENSE

更新履歴

Change Log

All notable changes to this project will be documented in this file (keepachangelog.com).

1.2.0 - 2017-12-21

Removed

  • Removed debug.

1.1.1 - 2016-08-01

Changed

  • Update readme.md with much nicer sauce-labs browser matrix from exogen/badge-matrix.

1.1.0 - 2016-08-01

Changed

  • Update zuul, nodemon, and dependency-check to latest versions per greenkeeper.
  • Update sauce open credentials in .travis.yml

Added

  • Add _.get to alternatives list per @jasonkarns
  • Add new sauce labs repo badge.
  • Add postversion npm script.

1.0.22 - 2016-07-13

Changed

  • Updated depedency-check, uglify, and standard to latest versions per greenkeeper.

1.0.21 - 2016-07-13

Added

  • Add debug logging.

Changed

  • Update .zuul.yml to test only firefox versions 44..46 instead of just latest.

1.0.18 - 2016-05-02

Added

  • Add API usage example for case where value at path is a function and is automatically invoked.
  • This is an old feature but I've finally gotten around to adding a usage example.

1.0.17 - 2016-05-02

Fixed

  • (FIXED) Missing index.js in published packages after 1.0.8 #28.
  • Corrected an issue where using files in package.json does not publish index.js.
  • Fix was to drop files and instead explicitly ignore unwanted files via .npmignore.

1.0.9 - 2016-03-05

Changed

  • Updated dependencies.

1.0.8 - 2016-03-05

Added

  • add demo .gif to readme.md.

1.0.7 - 2016-03-05

Removed

  • Remove iphone from list of sauce-labs browsers to test as it has been flaky as of late.

1.0.6 - 2016-03-03

Added

  • Add example of support for keys containing . (array path).

1.0.5 - 2016-02-03

Fixed

Changed

  • Updated bower.json including dropping of deprecated key/values (i.e. version).

1.0.0 - 2016-01-27

Fixed

  • Drop support for traversing into falsey objects (fixes #22)
  • Failing on undefined param (fixes #21)
  • Array prefixes do not get resolved (fixes #11)
  • remove automatic global handling (fixes #10)

Added

  • Add contributing.md.
  • Add development task npm run dev which uses nodemon to re-running npm test on file changes.
  • Add dependency check task npm run dependency:check.
  • Add dependency check task npm run fixpack.
  • Add Zuul for browser testing & connect to .travis.yml.
  • Add browser test task npm run test:browsers.

Changed

  • Convert History.md to changelog.md (keepachangelog.com).
  • Switch from mocha to tape for unit tests.
  • Switch to "JavaScript Standard Style" (https://github.com/feross/standard).
  • Refactor source to depend on brackets2dots, dotsplit.js, and curry2.
  • Comprehensive package.json.

Removed

  • Drop component.json.
  • Removed examples directory in favor of concise examples in readme.md.

0.10.0 - 2015-09-08

Changed

  • accepts an array of properties.
  • better support for accessing falsy primitive values.
  • added bower configuration allowing bower installer to work.

0.9.6 - 2013-11-11

Changed

  • documentation cleanup.

0.9.0 - 2013-09-08

Changed

  • generates standalone module via browserify instead of component(1).

0.8.4 - 2013-08-02

Fixed

  • [bugfix] correctly support nested array syntax.

0.6.0 - 2013-06-28

Added

  • [feature] optional partial application (via currying).
  • [feature] access global object if no object reference is given.

0.2.3 - 2013-03-10

Added

  • First stable release.