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
  • 1
    \$\begingroup\$ I believe that your code would fail with an input like 'axab' \$\endgroup\$ Nov 3, 2018 at 20:10

1 Answer 1

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\$
2
  • \$\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\$ Nov 3, 2018 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\$ Nov 3, 2018 at 21:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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