0

Given a variable str containing a string value, are these two lines of code equivalent?

Line A:

if ( [ 'foo', 'bar', 'baz' ].indexOf( str ) > -1 ) { 

Line B:

if ( /^foo|bar|baz$/.test( str ) ) { 
2

3 Answers 3

2

Not quite. The pipes are including the ^ and $ as alternatives. I'm not entirely clear on the syntax of JS's regular expressions, but if you're looking for str to contain only foo, or bar, or baz, use the expression /^(foo|bar|baz)$/. If you're looking to do something different, let me know and I'll try to clear it up.

Sign up to request clarification or add additional context in comments.

3 Comments

I would like to achieve the behavior of Line A with Line B. (So, yes, I want to check if str is exactly one of those 3 values... )
Then yes, you want the regex I gave you. Alternately, if you don't need to capture /which/ value you match, you can use /^(?:foo|bar|baz)$/. The ?: means 'don't bother remembering which one of these three matches', and it might be a bit faster
Could you explain why i have to group my a|b|c? How does it make a difference?
1

No, they are not.

The method indexOf() returns -1 if the item is not found in the array, or the position of the array if it is found in the array.

The method test returns true if the regex finds a match, and false if it doesn't.

If your regular expression was instead /^(foo|bar|baz)$/, then the function would be the same.

2 Comments

But why are the parens required?
@ŠimeVidas Because /^foo|bar$/ is ^foo OR bar$, and thus would match "fools", and would also match "sandbar".
1

Okay, after the edit, they're still not equivalent since test will call toString. See:

var myItem = {toString: function() { return 'foo'; }}; ['foo', 'bar', 'baz'].indexOf(myItem); // -1 /^(foo|bar|baz)$/.test(myItem); // true 

http://jsfiddle.net/hqu7D/

Even when they're string values (sorry, missed that) then they're still not equivalent because there are two different types of strings and indexOf uses strict equality/identity:

http://jsfiddle.net/HpCUY/

To make them truly equivalent, you can either call .toString() before using indexOf, or you can test Object.prototype.toString.call(myItem) === '[object String]' before using test.

7 Comments

Still they're different. Minitech gave you a few examples of things that B will catch that A will not, and see the regex I gave you for how to fix it.
@minitech Yes, but I mentioned in my question that str is a string value... It can't be an object.
@ŠimeVidas: Sorry, missed that. I edited my answer again - they're still not equivalent.
@minitech Uh... :) When I said "string value", I meant a value of the String type, not a String object... (String objects are useless, I would never use them... )
@ŠimeVidas: I know :) But your question is tagged theory, and this is a possibility. jQuery does it too.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.