Nesting for loops to find matches in different tables I'm not sure if I'm even approaching this correctly (still very much learning), but this is what I'm attempting to accomplish:
My script gets an array from a column (tab names of the sheet) and then calls another function to copy those tabs (this part works fine).  What I'm attempting to add is a separate list of properties that I want to assign to each copied sheet (visibility, color, etc.)  This secondary list is on another tab, so my thought was that within my first loop (that determines which tabs to copy), I would have a nested loop that would find the match to the tab name and then bring those variables in to be associated with the sheet name.
My secondary for loop works, but it seems counter intuitive or somewhat redundant.  It feels like a lot of wasted effort to loop through the &quot;properties array&quot; for every loop, but maybe it is necessary.
function getSheetArray(ui, ss, settingsSheet, updateID, latestVersion, versionRangeName, updateSheet, updateSheetsSheet, sheetsToUpdateRangeName, updateSheetsVals) {
  var updateSheetsLength = updateSheetsVals.filter(String).length;
  if (updateSheetsLength == null) {
    return
  }
  var sheetDataRange = updateSheetsSheet.getRange(2, 1, updateSheetsLength, 1);
  const sheetData = sheetDataRange.getValues();

  var updateSheet = SpreadsheetApp.openById(updateID);
  var tabSheet = updateSheet.getSheetByName(&quot;tabDefinitions&quot;);
  var tabDataRange = tabSheet.getRange(2, 1, tabSheet.getMaxRows() - 1, tabSheet.getMaxColumns());
  const tabData = tabDataRange.getValues();
  var tabProps = [];
  for (var i = 0; i &lt; sheetData.length; i++) {
    var sheetName = sheetData[i];

    for (var j = 0; j &lt; tabData.length; j++) {
      if (sheetName == tabData[j][0]) {
        var tabProps = [
          tabName = tabData[j][0],
          tabVisibility = tabData[j][3],
          tabUpdVisibility = tabData[j][4],
          tabClearData = tabData[j][5],
          tabFormat = tabData[j][6],
          tabPosition = tabData[j][7],
          tabColor = tabData[j][8]
        ];
      }
    }
    console.log(&quot;tabProps = &quot;, tabProps);
    console.log(&quot;tabName = &quot; + tabName);
  }
}
I don't know enough about the shape of testData to write great code, but you could preprocess and convert testData from an array to an object or Map of key-value pairs. By using the first element of each item in testData as the key, then you can convert your \$O(n)\$ inner &quot;search&quot; loop into a constant time \$O(1)\$ key lookup. This would reduce your overall complexity from something on the order of \$O(n^2)\$ to a nicer linear \$O(n)\$ algorithm.
Note: This assumes your data has unique values sitting at index 0 of each element in the main array. The difference being your code returns the first match, but the following technically return the last match as duplicate key overwrite existing value(s).
Something like:
var tabData = tabDataRange
  .getValues()
  .reduce((tabData, data) =&gt; ({ ...tabData, [data[0]]: data }), {});

Then your loop becomes
for (var i = 0; i &lt; sheetData.length; i++) {
  var sheetName = sheetData[i];

  if (tabData[sheetName]) {
    var data = tabData[sheetName];
    var tabProps = [
      tabName = data[0],
      tabVisibility = data[3],
      tabUpdVisibility = data[4],
      tabClearData = data[5],
      tabFormat = data[6],
      tabPosition = data[7],
      tabColor = data[8]
    ];
    break; // &lt;-- found data, break out of loop early
  }
  console.log(&quot;tabProps = &quot;, tabProps);
  console.log(&quot;tabName = &quot; + tabName);
}