0

I have a very simple function I am trying to add to an array. I have seen examples on this site where people have extended different simple items, like String & Array. But I also have seen comments where Google doesn't allow you to extend certain classes. But from what I can tell, that was only for custom Google classes, like Spreadsheet, Range, etc.

Why is this throwing a TypeError? Tried to use the same function I found here.

Array.prototype.findIndex = function(search){
  if(search == "") return false;
  for (var i=0; i<this.length; i++)
    if (this[i] == search) return i;

  return -1;
} 

//Do a search on a specific range, find the correct ID, and do a lookup based on ID
function onEdit(e) {
  var e = {};
  e.value = "Test String";
  var client = e.value;
  var columnValues = mydoc.getRangeByName(categoryRangeName).getValues();

  //columnValues returns 2D array of values
  //https://developers.google.com/apps-script/reference/spreadsheet/range#getValues()
  var searchResult = columnValues.findIndex(e.value);  //**ERROR HERE**

}

UPDATE

I will also add, that I set the method to just return a value like this just to test that there was no problem with the prototype, and it failed on the same error.

Array.prototype.findIndex = function(val) {
  return val;
} 

And I created a function with the same for loop, and it works just fine.

function findIndex(vals, search) {
  if(search == "") return false;
  for (var i=0; i<vals.length; i++)
    if (vals[i] == search) return i;

  return -1;
}
Community
  • 1
  • 1
Nathan
  • 2,941
  • 6
  • 49
  • 80

1 Answers1

2

The findIndex function, search on a 1D array, however, you have a 2D array. You must change the findIndex function to search on a 2D array.

Array.prototype.findIndex = function(search) {
  if(search === '') return false;
  for (var i = 0, len = this.length; i < len; i++)
    if (this[i] === search) return i;
  return -1;
}

function onEdit(e) {
  var search_text = 'Test String';
  var columnValues1D = ['String Test', 'Test String'];
  var columnValues2D = [['String Test'], ['Test String']];
  Logger.log(columnValues1D.findIndex(search_text)); // <-- 1
  Logger.log(columnValues2D[0].findIndex(search_text)); // <-- -1
  Logger.log(columnValues2D[1].findIndex(search_text)); // <-- 0
}

UPDATE

Array.prototype.findIndex = function(search) {
  if(search === '') return false;
  for (var i = 0, len = this.length; i < len; i++)
    if (this[i][0] === search) return i;
  return -1;
}

function onEdit(e) {
  var search_text = 'Test String';
  var columnValues2D = [['String Test'], ['Test String']];
  Logger.log(columnValues2D.findIndex(search_text)); // <-- 1
}
wchiquito
  • 16,177
  • 2
  • 34
  • 45
  • That's what I thought too. But I created a findIndex function, and passed in my 2D array and search value, and the exact same for loop found a match and worked? Updating my question. – Nathan Dec 08 '13 at 18:05
  • 1
    @Nathan: The new `findIndex()` function, which is not added/injected into the Array prototype does a search on a 2D array. – wchiquito Dec 08 '13 at 18:25
  • So why does the method still error/fail when I just have it `return val;` ? – Nathan Dec 08 '13 at 19:02
  • @Nathan: I do not understand what you said with the `return val;`. The updated answer you can see the `findIndex()` function to search a 2D array. – wchiquito Dec 08 '13 at 19:21
  • Thanks. I think my problem lies elsewhere. I put your code in my current script, and it failed. But I created a completely blank one and only pasted in your code, and it worked. I will figure out where my problem lies. Thanks! – Nathan Dec 08 '13 at 19:27
  • Oh, when I said `return val`, I was referring to my test method in the original question. – Nathan Dec 08 '13 at 19:37
  • What sense does this make? A 2D Array is still an array where the callback could be called on any element in the first dimension. In the callback you could adress the element that is handed as an arg as a 1D array item[0] ... Why is there no findIndex on multidimensional arrays? – haemse Jun 15 '18 at 02:04