0 votes
by (1.3k points)

So, I have this:

setup.getPreset = function () {
	var svpreset = State.variables.preset;
	var result;
	Object.keys(svpreset).forEach(function (gender) {
		if (svpreset[gender] === true) {
			result = gender;
		}
	});
	return result;
};

And this works. It does exactly what I want. But it sure wasn't my first attempt at getting this result. Is there some nice function that will break out of an iteration and return a value other than a truth value?

I've tried .some and .every, but they won't return the value. Just the success. So, if I do this:

setup.getPreset = function () {
	var svpreset = State.variables.preset;
	return Object.keys(svpreset).every(function (gender) {
		if (svpreset[gender] === true) {
			return = gender;
		}
	});
};

All it does is return true or false, if it can find it or not.

So... nifty function that plays nice? Or is the method I do have a good enough solution? It's clunky. Super super clunky, but it works. So, that's good?

2 Answers

0 votes
by (156k points)
selected by
 
Best answer

As explained in the <Array>.forEach() documentation there is no break equivalent for that function...

There is no way to stop or break a forEach() loop other than by throwing an exception. If you need such behavior, the forEach() method is the wrong tool. Use a plain loop or for...of instead. ...

The following is an example of using the suggested for...of statement:

setup.getPreset = function () {
	var preset = State.variables.preset;
	var result = "";
	for (let key of Object.keys(preset)) {
		if (preset[key]) {
			result = key;
			break;
		}
	}
	return result;
};

note: The above also solves the use-case of when none of the properties on the preset object are set to true, which your solution didn't cover.

by (65.8k points)
edited by

There's absolutely nothing wrong with greyelf's answer, however, it's possible to do away with both the result variable and the assignment to it by using an early return.  For example:

setup.getPreset = function () {
	const preset = State.variables.preset;

	for (const gender of Object.keys(preset)) {
		if (preset[gender]) {
			return gender;
		}
	}

	return "";
};

If $preset is a generic object, then that could likely be further simplified to:

setup.getPreset = function () {
	var preset = State.variables.preset;

	for (var gender in preset) {
		if (preset[gender]) {
			return gender;
		}
	}

	return "";
};

This version also has the benefit of not requiring ES2015.

 

NOTE: To cause either example to return undefined when no match is made, as the first example in the question does, simply remove the final return statement.

by (1.3k points)
I see! Neat. I'll copy this too, in case I need this kind of code again.

I didn't get notified that someone responded to this question, hence the late reply. But thanks for the answers!
0 votes
by (1.3k points)
Oh, right. I've since moved away from this object model, to just having it as a simple string. So, I no longer use this function at all. But, I'm still curious if there's a better javascript method I should use for this kind of iteration.
Welcome to Twine Q&A, where you can ask questions and receive answers from other members of the community.

You can also find hints and information on Twine on the official wiki and the old forums archive.

See a spam question? Flag it instead of downvoting. A question flagged enough times will automatically be hidden while moderators review it.
...