1

Is there a native or library function for checking multiple keys at once?

Say this is my object:

const foo = {};
foo.superLongNameNeededByPackage = {cat: {black: 1}, hat: 2, bat:3, mat: 12}
console.log(foo);
// { superLongNameNeededByPackage : {cat: {black: 1}, hat: 2, bat:3, mat: 12} }

And I want to check that it has various keys on it, if there a way to do this?

const isReadyForHalloween = hasMultipleKeys(foo.superLongNameNeededByPackage,
  ['cat.black', 'hat', 'bat']);

I'm aware of lodash's has as well as the fact I can write my own using Object.keys and every but I was hoping to avoid it if possible, becuse it would still feel overly verbose and requires writing out the full formulation.

const arr = Object.keys(foo.superLongNameNeededByPackage);
arr.every(item => item.hasOwnProperty("a")
               && item.hasOwnProperty("b")
               && item.hasOwnProperty("c") );

But I don't want to be writing out hasOwnProperty each time, and may want to supply my key list as its own variable.

3
  • 3
    There is no built-in functionality like that. You can make a custom function or use a third party one, as you mentioned - it should be simple and if you need it in a lot of places, it would ultimately save you time and effort. Commented Sep 30, 2019 at 11:33
  • You could use _.every with _.has jsfiddle.net/ovejt8n6 Commented Sep 30, 2019 at 11:47
  • You can use flatten npm package which allows you to flat the object, it will tranform it into cat.black Commented Sep 30, 2019 at 13:41

4 Answers 4

1

You could take two functions, one to check the path and another to check if all keys are in the object.

function has(object, path) {
    return path.split('.').every(k => object.hasOwnProperty(k) && (object = object[k]));
}

function hasMultipleKeys(object, keys) {
    return keys.every(has.bind(null, object));
}

const foo = {};

foo.superLongNameNeededByPackage = { cat: { black: 1 }, hat: 2, bat: 3, mat: 12 };

const isReadyForHalloween = hasMultipleKeys(foo.superLongNameNeededByPackage,  ['cat.black', 'hat', 'bat']);
console.log(isReadyForHalloween);

Sign up to request clarification or add additional context in comments.

Comments

1

Although lodash doesn't have a built in function, you can create hasMultipleKeys() using _.overArgs().

The function takes the array of keys, and an object you wish to check. The array is passed directly to _.every() (via _.identity()), while the object is applied to _.has() (using _.curry()) to create the predicate for the _.every() function.

const hasMultipleKeys = _.overArgs(_.every, [_.identity, _.curry(_.has)])


const foo = {cat: {black: 1}, hat: 2, bat:3, mat: 12}
  
console.log(hasMultipleKeys(['cat.black', 'hat', 'bat'], foo)) // true
console.log(hasMultipleKeys(['cat.black', 'nothing', 'bat'], foo)) // false
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>

Comments

1

Here is my solution:

> const objectContains = (object, keys) => keys.every(k => k in object)
> const o = { a: 0, b: 1 }
> objectContains(o, ['a', 'b'])
true
> objectContains(o, ['a', 'b', 'c'])
false

Comments

0

I had the exact same question a few days ago. This is what I came across. It uses the flat package. https://www.npmjs.com/package/flat

      let foo;
      const obj = flatten(clonedObj, {maxDepth: 0});
      foo = ['yourkeys', 'yourkeys.secondLevel']
        .every(field => obj.hasOwnProperty(field) && !!obj[field]);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.