0

*****EDITED TO INCLUDE TRUE MINIMAL REPRODUCIBLE EXAMPLE*****

I have a nested for loop that reads elements from an array and writes to another array. The inner for loop is supposed to check elements in one of the arrays and break back to the outer array when the elements are not equal.

I have referenced stackoverflow for all related questions to try and find a solution. I have tried writing the array elements into variables and comparing them, but the result is the same; the if condition is triggering erratically and I cannot determine what the pattern is.

I have been using Logger.log in my test conditions and have managed to pinpoint the for statement that is causing the issues - but I haven't been able to find a solution.

function importCollection() {
  var xpacs = [[1], [1], [1], [1], [1], [1], [2], [2], [3], [3], [3]];
  var cards = [[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11]];

  var cards0 = [];
  var cards1 = [];
  var cards2 = [];
  var cards3 = [];
  var cards4 = [];

  var a = 0;
  var b = 0;
  var c = 0;
  var x = 0;
  var y = 11;

  for (b;c<y;b++) {
    x = xpacs[c];
//    Logger.log("x: "+x)
//    Logger.log("xpacs: "+xpacs[c]);
    PACK_LOOP: for (var a=0;a<5;a++) {
      if (c==y || x!=xpacs[c]) {  //  ***** ERROR - This is the code that is triggering too often
        Logger.log("Row: "+b);
        Logger.log("Col: "+a);
        Logger.log("Card: "+c);
        Logger.log(x);
        Logger.log(xpacs[c]);
        Logger.log("This if statement shouldn't be triggering when the two lines above are equal!");
        break PACK_LOOP
      }
      eval("cards"+[a]+"[b] = cards[c]");
      c++;
    }
  }
  Logger.log(cards0);
  Logger.log(cards1);
  Logger.log(cards2);
  Logger.log(cards3);
  Logger.log(cards4);
}

The expected results should be:

[[1.0], [6.0], [7.0], [9.0]]
[[2.0], null,  [8.0], [10.0]]
[[3.0], null,  null,  [11.0]]
[[4.0], null,  null,  null]
[[5.0], null,  null,  null]

Thank you to everyone for your help

Aaron Irvine
  • 343
  • 3
  • 13
  • Welcome to StackOverFlow please take this opportunity to take the [tour] and learn how to [ask] and [mcve]. You have a lot of undefined stuff in your code for example `cardCtr , xpacs` – Cooper Jun 07 '19 at 17:06
  • Is that better Cooper? I didn't post all the code in the question as it does state not to copy-paste entire blocks of code in the question. All relevant code is contained in the linked spreadsheet. I'll add the rest of it though. – Aaron Irvine Jun 07 '19 at 17:25
  • Please read this [mcve] and insure that your example meets the requirements. – Cooper Jun 07 '19 at 17:28
  • @Aaron Minimal and reproducible. 1.Start from scratch. Forget the cards, forget the spreadsheet. Use only a `for-loop`. Use array variables to replicate the data you'd receive from the spreadsheet. For eg, ``var valArr1 = [[1,2,3]]; var valArr2 = [[1],[2],[3]]; for(...){}``; Reproduce the problem within 5-10 lines of code.And your code should be independent and reproducible, i.e.,We should be be able to replicate the same issue(no undeclared var),when we copy-paste your code in our script editor(which is not attached to a sheet) and run the code. Eg: https://stackoverflow.com/questions/2641347 – TheMaster Jun 07 '19 at 17:59
  • 1
    Most questions don't strictly adhere to this criteria, but we do still answer them. But [mcve] is what's expected of you. – TheMaster Jun 07 '19 at 18:00
  • If you just need to see why the `if` block is being executed, have you tried using the [script editor debugger?](https://developers.google.com/apps-script/guides/support/troubleshooting) You click on the line number with the `if` condition and then run the function using the bug button. I also see you aren't dumping the value of `cardCtr`... perhaps you are too sure of what that variable contains. – dwmorrin Jun 08 '19 at 02:57
  • Thanks the for the clarification @TheMaster I understand it clearer now. I had cut 30+ sheets and a few thousand lines of code out of the spreadsheet and considered what I had presented as minimal reproducible but now I see what I need to do. Should I edit this question or delete it and post a new one with the amended code? – Aaron Irvine Jun 08 '19 at 05:37
  • @dwmorrin thanks for your input! I'll try that now - I wasn't entirely sure on how the script editor debugger worked so thank you for the extra information. The `cardCtr` value has been dumped and tested - I just took that (and a few other things) out of the code to not clog it up as much as I knew it wasn't a cause of the issue. I wouldn't be surprised if it's formatting related or something. The actual values of the array elements are equal textually (ie: RoS - RoS) but they are still triggering as not equal. Anyway, I'll get to work on what everyone has suggested. – Aaron Irvine Jun 08 '19 at 05:42
  • @dwmorrin unfortunately when I run the debugger it loads up the debugger window for 10 sec or so while running the script then it disappear again. I'm assuming because there's no specific "error" as such, and that I'm dumping to the log. – Aaron Irvine Jun 08 '19 at 05:50
  • Your choice, but we recommend [edit]ing your question and offering bounties to get attention(if needed) instead of adding a new question. But, if you think this question is unsalvageable, do delete and ask a new question. – TheMaster Jun 08 '19 at 06:00
  • Bounties? I'm not familiar with them sorry. – Aaron Irvine Jun 08 '19 at 06:19
  • 1
    *****EDITED TO INCLUDE TRUE MINIMAL REPRODUCIBLE EXAMPLE***** I hope this is what was expected and outlined in the comments? – Aaron Irvine Jun 08 '19 at 06:33

1 Answers1

1

An expression comparing Objects is only true if the operands reference the same Object

Array is a object. When you compare two objects, they'll always be false. At this point,

if (c==y || x!=xpacs[c])

If x and xpacs[c] are [1.0] and [1.0] respectively, Since you're comparing both objects,

[1.0] === [1.0] //false both objects don't refer the same object in memory
[1.0] !== [1.0] //true both objects don't refer the same object in memory
[1.0][0] === [1.0][0] //true as 1 === 1

You need to compare primitive values: (strings, numbers, boolean):

if (c==y || x[0]!=xpacs[c][0])
TheMaster
  • 45,448
  • 6
  • 62
  • 85