0

I understand that we can use something like

export function has(object, key) {
  object.hasOwnProperty(key)
}

to implement very basic behaviors of _.has. I am also aware of the standalone package of lodash.has does just the job.

But it seems to me that a _.has should not cost a few hundred lines. What are some shorter alternatives?

P.s. not a code golf question

Lil E
  • 388
  • 5
  • 23
  • 1
    Do you want to *mock* `_.has` or actually implement it? – VLAZ Apr 14 '20 at 07:15
  • Let's reverse a bit: if there is a readable alternative shorter than the current version, then basically there is either: crap in the version or some isofunctional better construct. In the latter case, it feels a bit odd, that such a library never benefitted from it... Are you asking to shrink down the cornercase or some behaviour to simplify code? If yes what should be kept or not ? – grodzi Apr 14 '20 at 07:23
  • Sorry I meant to implement it. Please check the updated question later. – Lil E Apr 14 '20 at 08:44
  • With the update - seems you just want a simpler version of [getting a property by path](https://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-and-arays-by-string-path). It wouldn't handle as many variations as Lodash does but you likely don't need to. Just change it to return a boolean, instead of the value. – VLAZ Apr 14 '20 at 09:37
  • For a higher level abstraction of this, you can look at functional lenses - these are generic and composable getters and setters of object properties. The idea is to "focus" an operation through a lens - so you can do something like `get(lens, obj)` which means "I want the value from `obj` described by this `lens`. You can also re-use it as something like `set(lens, obj, value)`. It wouldn't be a stretch to also have something like `has(lens, obj)`. Ramda.js has implementation of lenses but you can make your own or probably find a standalone one, if really needed. – VLAZ Apr 14 '20 at 09:37
  • @LilE I have added a implementation of `has`, you can check the answer – Koushik Chatterjee Apr 22 '20 at 17:39

1 Answers1

1

So, basically you are trying to create a alternative to _.has of lodash, but don'w want to write a thousand lines of code to handle all the possible corner cases. Here is a lighter version of has I implemented for you, that will not fall if the data is inappropiate (but obviously it is not going to handle as many cases handled in lodash).

I just simple took 2 inputs (as argument) 1: SOurce, 2: the Path (dot separated string/ keys or array of string), then just iterated through that keys and checked if that key exists or not, if exists, I updated the current source as the value that key contains, and folowed the same process.

Here is a Snippet:

function has(src, path = []) {
  let _path = Array.isArray(path) ? path.slice() : (path || '').split('.'),
    o = src,
    idx = 0;

  if (_path.length === 0) {
    return false;
  }

  for (idx = 0; idx < _path.length; idx++) {
    const key = _path[idx];

    if (o != null && o.hasOwnProperty(key)) {
      o = o[key];
    } else {
      return false;
    }
  }
  return true;
}

const obj1 = {a: {b: {c: {d: {e: {f: {g: { h: 210}}}}}}}};

//you can send the path as a array of sequential keys
console.log(has(obj1, ['a', 'b', 'c', 'd', 'e'])) // valid path
console.log(has(obj1, ['a', 'b', 'c', 'd', 'x', 'y'])) //invalid path

//Or, you can pass the path as a single string
console.log(has(obj1, 'a.b.c.d.e.f.g.h')) // valid path
console.log(has(obj1, 'a.x.y.b.c.d.e.f.g.h')) //invalid path
Koushik Chatterjee
  • 4,106
  • 3
  • 18
  • 32