5

I have a question relating to the answer on this post Javascript code to parse CSV data

I'm finding I get an extra "\r\n" on the end which I don't want to add to the array. I've tried to break out of the while loop...

The original working line is

 while (arrMatches = objPattern.exec( strData )){

but I need to break out if arrMatches = "\r\n"

while ((arrMatches[ 1 ] != "\\r\\n") && arrMatches = objPattern.exec( strData )){

but get an Invalid left-hand side in assignment error.

What is the correct syntax?

pretzelhammer
  • 13,874
  • 15
  • 47
  • 98
  • Can't you check on arrMatches[ 1 ] in the while loop? Something tells me that `arrMatches[ 1 ]` hasn't been assigned to any value while initializing `arrMatches`, which is done after `&& arrMatches = ..` – dbf Sep 13 '12 at 00:25
  • @dbf - your right. It gets assigned directly after that line from `arrMatches = objPattern.exec...`. Ok can i do something like `If (arrMatches[ 1 ] != "\\r\\n") {Exit while}`? –  Sep 13 '12 at 00:28
  • Try to flip it? `while (arrMatches = objPattern.exec( strData ) && (arrMatches[ 1 ] != "\\r\\n")){`, I don't really know the behaviour of the while loop condition in javascript – dbf Sep 13 '12 at 00:29
  • And yes, you can eventually use an `if` and `break;` if flipping the two doesn't work – dbf Sep 13 '12 at 00:34
  • Ah okay it's break I was looking for.. Flipping isn't working for either 'while (arrMatches = objPattern.exec( strData ) && (arrMatches[ 1 ] != ...' or just `arrMatches !=`. –  Sep 13 '12 at 00:36
  • Yea, then most likely (an assumption) the assigned value in arrMatches isn't available in the scope of the while's condition until it reaches the while's body code, it differs per language. – dbf Sep 13 '12 at 00:42
  • Ok, forget my previous comment, flipping the conditions with extra `( )` should work, see my answer ;) – dbf Sep 13 '12 at 01:03
  • 2
    That error is because `&&` has a higher precendence than `=`. [(Further info.)](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Operator_Precedence#Table) – nnnnnn Sep 13 '12 at 01:45
  • @nnnnnn I believe the precendence is checked on logical not `!` against functional `()`, not `&&` or `=` – dbf Sep 13 '12 at 12:03
  • @nnnnnn Ah stupid, that's totally true for the while structure in his question. It does still not make sense to me why the error for invalid left-hand side occurs, even if `arrMatches` is not initialized with a value, it should have said `TypeError(or ReferenceError): arrMatches is undefined`, doesn't it? – dbf Sep 13 '12 at 14:30
  • The JS engine parses the entire function before it executes it, so the invalid left-hand error is found at that point. If you fix that with parentheses then when the function is actually executed you'll get the reference error the first time the while expression is evaluated. – nnnnnn Sep 13 '12 at 22:37

6 Answers6

7

just separate the two conditions to make it more readable and understandable

while(arrMatches = objPattern.exec( strData )){

    if(arrMatches[ 1 ] == "\r\n"){
        break;
    }
    /*
     *if(arrMatches[ 1 ] == "\r\n")
     *   break;
     */
     // rest of code
}
zeacuss
  • 2,563
  • 2
  • 28
  • 32
5

This approach should work, the only thing is that arrMatches should be between ( ) too, to avoid arrMatches being set to true from the second condition.

while ((arrMatches = objPattern.exec( strData )) && (arrMatches[ 1 ] != "\\r\\n")) {
dbf
  • 3,278
  • 1
  • 24
  • 34
3

Another way: the expression block of the while operator can be easily split up into a chain of comma-separated expressions expecting the loop to break once the last expression evaluates to 0/false.

It's NOT equivalent to logical && chaining since a comma ',' operators in JS always return the last expression. (Thanks GitaarLab to remind me about that)

In these examples the loop stops once the last variable reaches 0 and thus evaluates to false.

var i = 10, j = 10;
while (i--, j--) console.log(i);
/*9
8
7
6
5
4
3
2
1
0*/

var i = 10, j = 5;
while (i--, j--) console.log(i);
/*9
8
7
6
5*/

var i = 10, j = 5, k = 3;
while (i--, j--, k--) console.log(i);
/*9
8
7*/
Arman
  • 5,136
  • 3
  • 34
  • 36
  • 1
    Sorry, but I must downvote (not because I've spent a day tracking down my bug that came from your answer, but) because it is currently wrong and misleading to say: `the expression block of the while operator can be easily split up into a chain of expressions with the comma ",". It's equivalent to logical && chaining.` It is NOT equivalent to `&&` since only the last result is returned (so no `&&` or `||`)! Try: `var i=10,j=5,k=3;while(k--,j--,i--)alert(i);` (or [fiddle](http://jsfiddle.net/TXbqP/)) to see the proof. Please don't delete (but fix) your answer so other 'ninja' coders are warned!! – GitaarLAB Aug 08 '13 at 13:39
  • @GitaarLAB, they are warned, thanks ;) I'd also suggest to avoid using commas in loop expression bodies. I'm sure it's there because of the general comma-operator existence in javascript rather than from any practical meanings. This reply is to expose one additional feature of the language - but not to propagate its usage in real production code. – Arman Sep 16 '13 at 07:05
  • so.. just to be on the clear side: in your example 'the loop **does not** stop once *one* of the variables reaches 0 and thus evaluates to false', *but if the **last** value reaches 0!!!* Try the example from my first comment: the loop should count down from 3 (variable k) and stop, but it doesn't!! It counts back from 10 (variable i). Thus you can't use the comma-operator to exit a loop based on 2 conditions (yet your answer has value in pointing out that you *can't* do it that way). PS: Just like ternary operators etc I sometimes like using the comma-operator in loop expressions. – GitaarLAB Sep 16 '13 at 07:31
  • @GitaarLAB, did it. better late than never :) – Arman Jul 04 '14 at 13:13
1

You could try a while loop that handles one condition, and inside the while loop, you have an if statement that checks the other condition.

Example:

while (one condition) {
   if (other condition) {
       do something;
   }
}

Whether this is the appropriate way to do it, I'm not entirely sure. I'll update my answer if I find something better.

aug
  • 11,138
  • 9
  • 72
  • 93
0

Try: while ((arrMatches[ 1 ] != "\r\n") && arrMatches == objPattern.exec( strData )){

With a single '=', you are actually assigning a value to arrMatches. In order to compare values you should use ==.

lleite
  • 166
  • 4
  • Assignment is intended, it's a shortcut that does assignment and evaluation in one step (and leads to confusion). – RobG Sep 13 '12 at 00:39
-1
collection = [];
// while loop will run over and over again
while (true) { 
  //declare a variable which will store user input
  var conditionToo = prompt('What is the condition of the weather?');
  if (conditionToo == 'yes') { 
    // if the variable conditionToo contains the string 'yes'
    do something; //append values to the collection
  }
  if else(conditionToo == 'no') {
    // if the variable conditionToo contains string 'no'
    alert('Goodbye cool human :-)');
    break;
   }
}
Owen Kelvin
  • 14,054
  • 10
  • 41
  • 74
  • This is an OK answer that does present an interesting use of a while loop but it doesn't really seem to address the question, which is really just that there's a syntax error in the original condition, specifically the single = which is assignment not == which is comparison. Also the code in the answer is unformatted and hard to read. – Sloloem Oct 14 '20 at 18:37