If I have an object, such as:
const obj = {
field1: {
subfield1: true,
subfield2: true,
},
field2: {
subfield3: true,
},
field3: {
subfield4: false,
subfield5: true,
}
}
Then I can do a nested for loop to return true if a value is false
by doing,
const findFalse = obj => {
for (const field in obj) {
for (const subfield in obj[field]) {
if (!obj[field][subfield]) return true
}
}
}
If this object wasn't nested, it'd be a bit easier, I could do something like,
const findFalse = obj => Object.keys(obj).some(prop => !obj[prop]);
Both approaches don't really suit what I need, because the object can have 2, 3 or more nested properties. I've come up with a recursive way to figure this out, such as:
const isObj = obj => obj && obj.constructor === Object;
const findFalseRecursively = obj => {
for (const field in obj) {
if (isObj(obj[field]))
return findFalseRecursively(obj[field])
if (obj[field] === false)
return true
}
}
But I'm wondering if there's a cleaner or more efficient way of achieving this?
I would expect the function to return the first false
value that it sees, and break out of the function/for loop instantly.
A nested data structure is an array or object which refers to other arrays or objects, i.e. its values are arrays or objects. Such structures can be accessed by consecutively applying dot or bracket notation.
Vanilla JavaScript refers to using plain Javascript without any additional libraries or frameworks. The term became popular when Eric Wastl created the Vanilla JS site in 2012 as a joke. The site tries to bring attention to the fact that you can use just plain Javascript in many cases.
Creating Nested Objects in JavaScript Dynamically In ES6, Objects can be created with computed properties. To use a “dynamic” key, you have to use bracket notation: Iterate through the elements of basis . Use the keys to find the corresponding element in nested , and use that as the key in the new object being created.
To update nested properties in a state object in React: Pass a function to setState to get access to the current state object. Use the spread syntax (...) to create a shallow copy of the object and the nested properties. Override the properties you need to update.
You could take the valus from the object and iterate with a short circuit.
const
hasTrue = object => Object
.values(object)
.some(v => v === false || v && typeof v === 'object' && hasTrue(v)),
object = { field1: { subfield1: true, subfield2: true }, field2: { subfield3: true }, field3: { subfield4: false, subfield5: true } };
console.log(hasTrue(object));
With suggested check object in advance
const
hasTrue = value => value === true || !!value && typeof value === 'object' && Object
.values(value)
.some(hasTrue),
object = { field1: { subfield1: true, subfield2: true }, field2: { subfield3: true }, field3: { subfield4: false, subfield5: true } };
console.log(hasTrue(object));
Here is a simple recursive solution that uses Object.values
,flat
and some
.
function toValues (obj) {
if (typeof obj === 'object') return Object.values(obj).map(toValues);
return obj;
}
const findFalse = obj => toValues(obj).flat().some(v => v === false)
const res = findFalse(obj);
console.log (res);
<script>
const obj = {
field1: {
subfield1: true,
subfield2: true,
},
field2: {
subfield3: true,
},
field3: {
subfield4: false,
subfield5: true,
}
}
</script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With