Search code examples
javascriptlodash

Get last defined element in path of lodash.get(object, path)


Given an object:

const obj = {
  a: {
    b: {
      c: {
        d: 5
      }
    }
  }
};

I want a function similar to lodash.get(obj, path), which returns the last defined variable in the path:

console.log(_.something(obj, 'a.b.c.d')) // 5, which is obj.a.b.c.d
// because obj.a.b.c.d is defined

console.log(_.something(obj, 'a.b.c.e')) // { d: 5 }, which is obj.a.b.c
// because the path is only defined up to obj.a.b.c

console.log(_.something(obj, 'a.b.f')) // { c: { d: 5 } }, which is a.b
// because the path is only defined up to a.b

I can write it myself, but I wonder if I can do it with an existing lodash function. I've looked through the documentation, but nothing caught my eye.

Here's a rough implementation of what i want:

const safeGet = (object, path) => {
  const keys = path.split('.');
  let current = object;

  for (var i = 0; i < keys.length; i++){
    const val = current[keys[i]]
    if (val === undefined){
      return current;
    }
    current = val;
  }
}

Solution

  • There isn't a way to do that in Lodash by default, but here is a simpler function that I wrote than the one you currently have displayed. Hopefully this helps!

    const obj1 = {
      a: {
        b: {
          c: {
            d: 5
          }
        }
      }
    };
    
    const obj2 = {
      a: {
        b: {
          c: {}
        }
      }
    };
    
    function getLastDefined(obj, searchPath) {
      return _.get(obj, searchPath) || getLastDefined(obj, _.chain(searchPath).split('.').reverse().tail().reverse().join('.').value());
    }
    
    console.log(getLastDefined(obj1, 'a.b.c.d'));
    console.log(getLastDefined(obj2, 'a.b.c.d'));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.min.js"></script>