selectn
Version:
Curried property accessor function that resolves deeply-nested object properties via dot/bracket-notation string path while mitigating TypeErrors via friendly and composable API.
258 lines (214 loc) • 6.02 kB
JavaScript
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.selectn=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
const curry2 = require('curry2')
const dotted = require('brackets2dots')
const splits = require('dotsplit.js')
const string = Object.prototype.toString
module.exports = curry2(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.
*
* @param {String|Array} path
* Dot/bracket-notation string path or array.
*
* @param {Object} object
* Object to access.
*
* @return {Function|*|undefined}
* (1) returns `selectn/1` when partially applied.
* (2) returns value at path if path exists.
* (3) returns undefined if path does not exist.
*/
function selectn (path, object) {
let idx = -1
const seg = string.call(path) === '[object Array]' ? path : splits(dotted(path))
const end = seg.length
let ref = end ? object : undefined
while (++idx < end) {
if (Object(ref) !== ref) return undefined
ref = ref[seg[idx]]
}
return typeof ref === 'function' ? ref() : ref
}
},{"brackets2dots":2,"curry2":3,"dotsplit.js":4}],2:[function(require,module,exports){
;
/*!
* exports.
*/
module.exports = brackets2dots;
/*!
* regexp patterns.
*/
var REPLACE_BRACKETS = /\[([^\[\]]+)\]/g;
var LFT_RT_TRIM_DOTS = /^[.]*|[.]*$/g;
/**
* Convert string with bracket notation to dot property notation.
*
* ### Examples:
*
* brackets2dots('group[0].section.a.seat[3]')
* //=> 'group.0.section.a.seat.3'
*
* brackets2dots('[0].section.a.seat[3]')
* //=> '0.section.a.seat.3'
*
* brackets2dots('people[*].age')
* //=> 'people.*.age'
*
* @param {String} string
* original string
*
* @return {String}
* dot/bracket-notation string
*/
function brackets2dots(string) {
return ({}).toString.call(string) == '[object String]'
? string.replace(REPLACE_BRACKETS, '.$1').replace(LFT_RT_TRIM_DOTS, '')
: ''
}
},{}],3:[function(require,module,exports){
/*!
* imports.
*/
var bind = Function.prototype.bind || require('fast-bind')
/*!
* exports.
*/
module.exports = curry2
/**
* Curry a binary function.
*
* @param {Function} fn
* Binary function to curry.
*
* @param {Object} [self]
* Function `this` context.
*
* @return {Function|*}
* If partially applied, return unary function, otherwise, return result of full application.
*/
function curry2 (fn, self) {
var out = function () {
if (arguments.length === 0) return out
return arguments.length > 1
? fn.apply(self, arguments)
: bind.call(fn, self, arguments[0])
}
out.uncurry = function uncurry () {
return fn
}
return out
}
},{"fast-bind":5}],4:[function(require,module,exports){
var toString = Object.prototype.toString
/**
* Transform dot-delimited strings to array of strings.
*
* @param {String} string
* Dot-delimited string.
*
* @return {Array}
* Array of strings.
*/
function dotsplit (string) {
var idx = -1
var str = compact(normalize(string).split('.'))
var end = str.length
var out = []
while (++idx < end) {
out.push(todots(str[idx]))
}
return out
}
/**
* Replace escapes with a placeholder.
*
* @param {String} string
* Dot-delimited string.
*
* @return {String}
* Dot-delimited string with placeholders in place of escapes.
*/
function normalize (string) {
return (toString.call(string) === '[object String]' ? string : '').replace(/\\\./g, '\uffff')
}
/**
* Drop empty values from array.
*
* @param {Array} array
* Array of strings.
*
* @return {Array}
* Array of strings (empty values dropped).
*/
function compact (arr) {
var idx = -1
var end = arr.length
var out = []
while (++idx < end) {
if (arr[idx]) out.push(arr[idx])
}
return out
}
/**
* Change placeholder to dots.
*
* @param {String} string
* Dot-delimited string with placeholders.
*
* @return {String}
* Dot-delimited string without placeholders.
*/
function todots (string) {
return string.replace(/\uffff/g, '.')
}
/*!
* exports.
*/
module.exports = dotsplit
},{}],5:[function(require,module,exports){
;
module.exports = function(boundThis) {
var f = this
, ret
if (arguments.length < 2)
ret = function() {
if (this instanceof ret) {
var ret_ = f.apply(this, arguments)
return Object(ret_) === ret_
? ret_
: this
}
else
return f.apply(boundThis, arguments)
}
else {
var boundArgs = new Array(arguments.length - 1)
for (var i = 1; i < arguments.length; i++)
boundArgs[i - 1] = arguments[i]
ret = function() {
var boundLen = boundArgs.length
, args = new Array(boundLen + arguments.length)
, i
for (i = 0; i < boundLen; i++)
args[i] = boundArgs[i]
for (i = 0; i < arguments.length; i++)
args[boundLen + i] = arguments[i]
if (this instanceof ret) {
var ret_ = f.apply(this, args)
return Object(ret_) === ret_
? ret_
: this
}
else
return f.apply(boundThis, args)
}
}
ret.prototype = f.prototype
return ret
}
},{}]},{},[1])(1)
});