2

I'm trying to filter a range by comparing it to another range. I couldn't figure out a way to do this with functions in Google Spreadsheets so I made my own.

function FilterByArray(range, filterRange)
{
  var rangeLength = range.length;
  var filterRangeLength = filterRange.length;
  var outputArray = [];

  for(i = 0; i < rangeLength; i++)
  {
    var rangeValue = range[i];
    for(ii = 0; ii < filterRangeLength; i++)
    {
      if(rangeValue == filterRange[ii])
      {
        outputArray.push(rangeValue);
      }
    }
  }
  return outputArray;
}

At first glance I thought this would work, and should process in milliseconds with only a couple thousand total iterations. I try and test it and it says Loading... for 10-20 seconds then errors out with Internal Error executing the custom function.

Why is this, and what can I do to fix it?

Edit: A note, I come from C#, so if there are any glaring issues in this that are unrelated to my question please let me know.

2

There is a way to intersect two arrays without a script: see How to get the intersection of two sets

One issue with your code is that all ranges of more than one cells are represented as double arrays for the scripts. E.g., a row 1 2 3 is [[1,2,3]] while a column of the same elements is [[1],[2],[3]]. (On the other hand, a single-cell range is just a value.) So you are comparing objects instead of values, which probably isn't going to do what you want, regardless of size.

I use this auxiliary function to flatten double arrays, turning them into single arrays; it also correctly handles one-cell ranges.

function flatten(arg) {
  if (arg.constructor === Array) {
    return arg.reduce(function(a, b) { return a.concat(b); });
  }
  else {
    return [arg];
  }
}

With that at hand, I'd write something like this:

function FilterByArray(range, filterRange) {
  var flatRange = flatten(range);
  var flatFilter = flatten(filterRange); 
  var outputArray = [];

  for (var i = 0; i < flatRange.length; i++) {
    var value = flatRange[i];
    if (flatFilter.indexOf(value) != -1) {
      outputArray.push(value);
    } 
  }
  return outputArray;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.