Skip to content

Instantly share code, notes, and snippets.

@plugn
Last active August 3, 2021 22:52
Show Gist options
  • Save plugn/52c1ab3bccb5b4e8d116d23cb3740fa8 to your computer and use it in GitHub Desktop.
Save plugn/52c1ab3bccb5b4e8d116d23cb3740fa8 to your computer and use it in GitHub Desktop.
magical comprehensions for JS Object instances
/**
* @title objectUtils.js
* @description magical comprehensions for JS Object instances
* @author Max L Dolgov, plugn@github.com
*
* Here is `var` keyword for ability to re-declare functions,
* it makes tweaking functions in browser console possible.
*
*/
var mapCollectionByProp = (list, fieldName) => list.reduce( (acc, v) => ({ ...acc, [v[fieldName]]: v }), {})
var composeObject = (object, iterator = val => val, keys = Object.keys(object)) =>
keys.reduce((acc, field) => ({ ...acc, ...iterator(object[field], field)}), {})
var filterObject = (object, callback) => composeObject(object, (val, key) => (callback(val, key) ? {[key]: val} : {}))
var mapObject = (object, callback) => composeObject(object, (val, key) => ({[key]: callback(val, key)}))
/**
* changes Object items recursively
* callback gets object's value and key pair and may return object with multiple keys
*
* @param source {object|array|*} -
* @param mapper {function} -> {object}
* @returns {object|array|*}
*/
function walkObject (source, mapper = (v, k) => ({[k]: v})) {
if (typeof source !== 'object' || source === null || source === undefined) {
return source
}
if (Array.isArray(source)) {
return source.map(v => walkObject(v, mapper))
}
return Object.keys(source).reduce((acc, key) => ({
...acc,
...(mapper(walkObject(source[key], mapper), key))
}),
{})
}
var getCycleIndex = (position, length) => (position + length) % length
function moveListItem(list, index, step) {
const position = getCycleIndex(index + step, list.length)
list.splice(position, 0, list.splice(index, 1)[0])
}
var range = (min, max) => Array.from(Array(max - min + 1).keys()).map(v => v + min)
var uniqList = list => list.filter((v, i) => list.indexOf(v) === i)
var initList = (length, initialValue) => Array(length).fill(null).map(item => initialValue)
var getFlattenTreeReducer = (subTreePropName = 'children') => {
const reducer = (acc, item, index) =>
([
...acc,
{...item, _treeNodeId: String(index)},
...(item[subTreePropName]
? item[subTreePropName].reduce(reducer, [])
.map(v => ({...v, _treeNodeId: String(`${index}:${v._treeNodeId}`) }))
: [])
])
return reducer
}
var flattenTree = (treeData = [], subTreePropName) => treeData.reduce(getFlattenTreeReducer(subTreePropName), [])
/**
* gets value of nested property
*
* @param obj {object|array}
* @param path {string}
* @param def - default value
* @returns {*}
*/
export function getNested(obj, path, def = undefined){
const splitter = '[].'
const listQueryParts = String(path).split(splitter)
if (listQueryParts && listQueryParts.length > 1) {
const list = getNested(obj, listQueryParts[0])
if (Array.isArray(list)) {
return list.map(val => getNested(val, listQueryParts.slice(1).join(splitter)))
}
}
let key, val = obj
let arr = String(path)
.replace(/'|"|\]/g,'')
.replace(/\[/g,'.')
.split('.')
while ((key = arr.shift()) && 'object' === typeof val && val) {
val = undefined === val[key] ? def : val[key]
}
return val
}
// EOF %)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment