javascriptarraysrecursionecmascript-6ecma

Get value of Objet, according the "path"


Good morning, I have an object with this structure :

{
  instituts: {
    default: 999,
    users: { default: 888, email: 777 },
    docs: undefined,
    exams: { price: 3 },
    empowermentTests: 2,
    sessionsHist: 3
  },
  exams: { default: 0 },
  countries: 1,
  levels: 1,
  roles: { default: 1 },
  sessions: 1,
  tests: 1,
  users: { default: 3 },
  options: undefined,
  skills: { default: undefined }
}

And i have an array giving the path like ["instituts", "users"].

Thank to this array of paths, i want to parse my object and return the value of : instituts.users.default ( 'default', because after the path "users", there are not other entries and users type is an object)

An other example : path : ['instituts', "users", "email"] i want to have the value of : instituts.users.email (not 'default', cause in the object structure, email, is an integer, not an objet ).

I hope i am clear enought.

I tryed many things but i am lost with ES6 function : "filter / reduce / map ..."

Thank you for the help you can give.


Solution

  • I think this does what you're looking for:

    const getPath = ([p, ...ps]) => (o) =>
      p == undefined ? o : getPath (ps) (o && o[p])
    
    const getPowerNeed = (path, obj, node = getPath (path) (obj)) =>
      Object (node) === node && 'default' in node ? node .default : node
      
    const input = {instituts: {default: 999, users: {default: 888, email: 777}, docs: undefined, exams: {price: 3}, empowermentTests: 2, sessionsHist: 3}, exams: {default: 0}, countries: 1, levels: 1, roles: {default: 1}, sessions: 1, tests: 1, users: {default: 3}, options: undefined, skills: {default: undefined}}
    
    console .log (getPowerNeed (['instituts', 'users'], input)) //=> 888
    console .log (getPowerNeed (['instituts', 'users', 'email'], input)) //=> 777
    console .log (getPowerNeed (['instituts'], input)) //=> 999
    console .log (getPowerNeed (['instituts', 'exams', 'price'], input)) //=> 3

    I'm making the assumption that if the default value is not to be found, then you want to return the actual value if it exists. Another reasonable reading of the question is that you want to return the literal string 'instituts.users.email'. That wouldn't be much more difficult to do if necessary.

    The utility function getPath takes a path and returns a function from an object to the value at that path in the object, returning undefined if there are any missing nodes along that path. The main function is getPowerNeed, which wraps some default-checking around a call the getPath.