I'm a bit of a JS noob and I'm currently trying to learn array functions.
When trying to refactor some of my old code I stumbled across this:
export const determineValue = (events) => {
let eligible = false
for (const event of events) {
if (event.eventType === "1") {
eligible = true
} else if (event.eventType === "2") {
eligible = false
return eligible
}
}
return eligible
}
For this case, "1" and "2" are the only possible values of event.eventType.
How can I write this compactly?
Are there any best practices to consider here?
Thanks in advance for any clarification!
3 Answers 3
A simplified solution would be
//example setup
const events = [{"eventType":"1"},{"eventType":"2"}];
// Solution
const eventTypes = events.map(x => x.eventType);
return eventTypes.includes("1") && !eventTypes.includes("2");
Comments
Since the eligble events are type 1 - all you need to do is filter the events array for those and then return the length of the filtered array.
const events =[{eventType: 1},{eventType: 1},{eventType: 2},{eventType: 2},{eventType: 1},{eventType: 1}];
const determineValue = (events) => {
return events.filter(x => x.eventType === 1).length
}
;
console.log(determineValue(events)); // gives 4 events are type 1
console.log(events.length); // gives 6 events in total
To enhance it and you can also pass in the type that you want to count (in case you want to count the ineligible events instead)
const events =[{eventType: 1},{eventType: 1},{eventType: 2},{eventType: 2},{eventType: 1},{eventType: 1}];
const determineValue = (events, value) => {
return events.filter(x => x.eventType === value).length
}
;
console.log(determineValue(events, 1)); // gives 4 events are type 1
console.log(determineValue(events, 2)); //gives 2 events are type 2
console.log(events.length); // gives 6 events in total
Comments
I'd go with something like this :
const determineValue = (events) => {
return events.length > 0 && !(events.every(input => input.eventType === "2"));
}
If events.length > 0 is false, the part behind the && is not executed, and the function immediately returns false.
Otherwise it checks if every item in events has a value "2" for its property eventType. It returns false if the check succeeds and true if it fails, due to the ! in front of it.
Demo
const events0 =[];
const events1 =[{eventType: "1"}, {eventType: "2"}, {eventType: "1"}];
const events2 =[{eventType: "2"}, {eventType: "2"}, {eventType: "2"}];
const determineValue = (events) => {
return events.length > 0 && !(events.every(input => input.eventType === "2"));
}
console.log(determineValue(events0));
console.log(determineValue(events1));
console.log(determineValue(events2));
eventType's exist besides"1"and"2"?eventTypewith value"1". Soreturn events.every(event => event.eventType === "1"). Alternatively you can check if there is any property with value"2"and invert the outcome!events.some(event => event.eventType === "2").(There is probably a good duplicate for this somewhere.)falsewhen the array is empty. You can still use.every()or.some(), but you'll need an extra step:events.length === 0 ? false : events.every(event => event.eventType === "1"). (Though just a regular if-statement instead of a conditional operator might be better readable.)