Reputation: 1487
I have a problem to solve using some data from an object. The data could take a few forms and may or may not exist in the first place. For example
things : {
oranges: true,
apples : false
}
but it could equally be:
things : {
oranges: false,
apples : false
}
or maybe things
doesn't even exist
I need to:
1) Determine that things
exists
2) Determine that things
contains further keys
These two statements need to be verified in one callable function e.g thingsHasData()
3) If things
does have data, is any of the data set to true
?
This also needs to be a callable function e.g fruitsIsTrue()
4) Return the key for one of the true values
trueFruit()
- this should only return one key, but it doesn't matter which (it shouldn't ever have two true values as per business rules but it's more of a fallback to just return one if for some reason it does)
So I've been able to get the key of a true
key-value pair using the following:
var thingsList = {
things : {
oranges: false,
apples : true
}
}
var trueFruit = Object.keys(thingsList).filter(function(key) {
return thingsList[key];
});
return thingsList[0];
This correctly returns apples
and only apples so it works for point 4 but not the others, and I feel like there is a better way to do this not having to rely on repeating the same .filter
in a few different functions. Ideas?
Upvotes: 0
Views: 240
Reputation:
const thingsHasData = arg => (arg.things && Object.keys(arg.things).length>0) ? true : false;
const trueFruit = arg => {
if (!arg.things) return;
let fruitIndex = null;
let fruitValues = Object.values(arg.things);
fruitValues.forEach((value, index) => {
if (value) fruitIndex = Object.keys(arg.things)[index];
});
return fruitIndex;
}
Upvotes: 0
Reputation: 1063
var thingsList = {
things : {
oranges: false,
apples : true
},
things2 : {
oranges: true,
apples : true
}
};
function validateThings(things) {
// (1) checks for a falsy value of things
if (!things) {
return false;
}
var keys = Object.keys(things);
// (2) checks if things has keys
if (!keys.length) {
return false;
}
// (3) then it checks for every single keys value if it is truthy
for (var i = 0, len = keys.length; i < len; i++ ) {
if (things[keys[i]]) {
// (4) return this value — all tests passed
return things[keys[i]];
}
}
return false;
}
console.log(validateThings(thingsList.notInList));
console.log(validateThings(thingsList.things));
console.log(validateThings(thingsList.things2));
Upvotes: 1
Reputation: 2799
To check if the Object things
exist, you can use the following code:
if (typeof things != "undefined") {
// It exists!
}
To check if an object has any children, check Object.keys(things).length > 0
.
So the check for 1) and 2) would look like:
let things = {
oranges: true,
apples: false
}
if (typeof things != "undefined") {
// It exists!
if (Object.keys(things).length > 0) {
// It has children!
}
}
Upvotes: 1
Reputation: 386680
You could take functions and for a true
value, use Array#find
.
function thingsHasData(object) {
return 'things' in object;
}
function fruitsIsTrue(object) {
return 'things' in object && Object.values(object.things).some(Boolean);
}
function trueFruit(object) {
return 'things' in object && Object.keys(object.things).find(k => object.things[k]);
}
var a = {},
b = { things: {} },
c = { things: { oranges: true, apples : false } },
d = { things: { oranges: false, apples : false } };
[a, b, c, d].forEach(o => console.log(
thingsHasData(o),
fruitsIsTrue(o),
trueFruit(o)
));
Upvotes: 1