3
\$\begingroup\$

I'm relatively new to JavaScript and wonder whether my code is 'acceptable' for a practice exercise. Essentially, the function (successfully) returns true or false if the provided string has a letter 'b' 3 characters after a letter 'a' - e.g.:

Input:"after badly" - Output:"false"
Input:"Laura sobs" - Output:"true"

Could somebody advise me how it could be improved? Although it works, I wonder whether the best functions are used and whether its 'readability' could be improved (i.e. return trueOrFalse.some(answer) ).

function bThreeAfterA(a) {
	var b = (a.split(' ').join('')).split('a'); // creates array

	var trueOrFalse = b.map(function(c, i){ // puts into array true/false for each index
		if (c[2] == 'b') {
			console.log('value: ' + c[2] + ' is b; true');
			return true;
		} else {
			console.log('false');
			return false;
		}
	});
	
	var answer = function(el) {
 // checks whether any index is true
		return el === true;
	
};

	return trueOrFalse.some(answer); // return true/false
}

\$\endgroup\$
  • 1
    \$\begingroup\$ I believe that your code would fail with an input like 'axab' \$\endgroup\$ – Marc Rohloff Nov 3 '18 at 20:10
4
\$\begingroup\$

Using a regular expression is definitely the way to go — that's exactly what they are good at doing. The following regex looks for 'a', followed by any number of spaces, followed by a non-space character, followed by any number of spaces, followed by a non-space character, followed by any number of spaces, followed by 'b'.

function bThreeAfterA(str) {
    return /a *[^ ] *[^ ] *b/.test(str);
}

console.log('after badly', bThreeAfterA('after badly'));
console.log('Laura sobs', bThreeAfterA('Laura sobs'));

You should be aware, though, that you are using .some() suboptimally. The .some(callback) method stops executing as soon as the callback returns a true value. But you've already built trueOrFalse by analyzing the entire string, instead of taking advantage of that short-circuiting. Therefore, if you use .some(), you shouldn't also use .map().

function bThreeAfterA(str) {
    // Array of characters without spaces
    var chars = str.split(' ').join('').split('');
    return chars.some(function(c, i, chars) {
        return c == 'a' && chars[i + 3] == 'b';
    });
}

console.log('after badly', bThreeAfterA('after badly'));
console.log('Laura sobs', bThreeAfterA('Laura sobs'));

\$\endgroup\$
  • \$\begingroup\$ wow, very efficient and interesting solution, thanks! For the regex, I have no experience with this - does '/a' mean search for a, and '*' mean eliminate spaces, and '[^ ]' any character? Could you explain the regex? \$\endgroup\$ – user8758206 Nov 3 '18 at 21:50
  • 2
    \$\begingroup\$ I did explain the regex. Note that "eliminate" is the wrong way to think about it: the regex simply describes a pattern to search for. \$\endgroup\$ – 200_success Nov 3 '18 at 21:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.