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
}

200_success
145k22 gold badges190 silver badges478 bronze badges
asked Nov 2, 2018 at 19:44
\$\endgroup\$
1
  • 1
    \$\begingroup\$ I believe that your code would fail with an input like 'axab' \$\endgroup\$ Commented 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'));

answered Nov 2, 2018 at 22:57
\$\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\$ Commented 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\$ Commented Nov 3, 2018 at 21:53

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.