Skip to content

Instantly share code, notes, and snippets.

@bernardoadc
Last active August 19, 2021 04:38
Show Gist options
  • Save bernardoadc/aed52b55bac5e7d120db05ba64a6dba5 to your computer and use it in GitHub Desktop.
Save bernardoadc/aed52b55bac5e7d120db05ba64a6dba5 to your computer and use it in GitHub Desktop.
A vanilla one-liner similar to lodash's `_.set`

Usage: set(obj, 'a.b.c.d.e', value) || set(obj, [a, 'b', '@#$', 'd', 'e'], [1, 2, 3]) || set(arr, '0.1.2', true)

  • For bracket notation (e.g. obj['@#$']), use arrays
  • Creates arrays with numbered keys (numbers not allowed as objects keys, see other revisions for that)

Explanation

function set (
  obj,  // object in which to set nested properties
  path, // path of properties, as string or array
  value // value to set
) {
  return
    (path.split && path.split('.') || path) // if split exists, is a string (array of properties). Else, is array and ready to go
    .reduce( // reduce is handy to loop through each property, setting and retrieving them
    (o, k, i, a) => ( // "o" is the current nested property (object/array), "k" is the next property to set
      return
       (o || obj)[k] || // in first loop, "o" is nothing, so use obj. If property k exists already, get it
      ((o || obj)[k] =  // else set it
      (i==a.length-1) ? value : // if is the last property in the chain, its the one to set it
      (isNaN(a[i+1])? {} : [])) // else we need to set next step in chain. If next property is a number, this should be an array, else an object
    , 0)  // inicial "o" value, not really that important - could be anything
}
function set(obj, path, value){
return (path.split && path.split('.') || path).reduce(function(o, k, i, a){
return (o || obj)[k] ||
((o || obj)[k] = (i==a.length-1) ? value : (isNaN(a[i+1])? {} : []))
}, 0)
}
const set=(o,p,v)=>(p.split&&p.split('.')||p).reduce((O,k,i,a)=>(O||o)[k]||((O||o)[k]=(i==a.length-1)?v:(isNaN(a[i+1])?{}:[])),0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment