-1

This is my first time using Stack Overflow. I am a beginner level JavaScript/Google App Script coder.

I have a list of products that my app reads from 'Product' sheet and a list of keywords coming from 'Model' sheet. When running the code the app finds 2004 as a match for the keyword '200' I have tried different solutions but so far no success. This is my original code

Code

function onOpen(e) {
  CreateMenu();
}

function CreatseMenu() {
  // Add a custom menu to the spreadsheet.
  SpreadsheetApp.getUi() // Or DocumentApp, SlidesApp, or FormApp.
  .createMenu('Data Update')
  .addItem('Find Year', 'findYear')
  .addItem('Find Make', 'findMake')
  .addItem('Find Model', 'findModel')
  .addItem('Find Engine Size', 'findEngineSize')
  .addToUi();
}

const globalConst = {
  get ProductSpreadSheet() {
    delete this.ProductSpreadSheet;
    return (this.ProductSpreadSheet = SpreadsheetApp.openById('12HJqcc8sFghG3VM4YtFBNbTzzDdDnY4GNyDYQ37vBa8'));
  },

  get ProductSheet() {
    delete this.ProductSheet;
    return (this.ProductSheet = globalConst.ProductSpreadSheet.getSheetByName('Product'));
  },

  get ResultSheet() {
    delete this.ResultSheet;
    return (this.ResultSheet = globalConst.ProductSpreadSheet.getSheetByName('Result'));
  },

  get ProductSheetNumberOfRows() {
    delete this.ProductSheetNumberOfRows;
    return (this.ProductSheetNumberOfRows = globalConst.ProductSheet.getLastRow());
  },

  get ProductSheetValues() {
    delete this.ProductSheetValues;
    return (this.ProductSheetValues = globalConst.ProductSheet.getRange('A1:A' + globalConst.ProductSheetNumberOfRows).getValues());
  },
};



// This Function will find the Model of each product and records it in the result sheet (Column C)
function findModel() {
  var modelSheet = globalConst.ProductSpreadSheet.getSheetByName('Model');
  var modelSheetNumberOfRows = countRows(modelSheet);
  var modelSheetValues = modelSheet.getRange('A1:A' + modelSheetNumberOfRows).getValues();
  var modelColumnNumber = 3;

  this.getResults(modelSheetNumberOfRows, modelSheetValues, modelColumnNumber)  
}

// This function returns the number of the last row with value for a sheet 
function countRows(sheet) {
  var numberOfRows = sheet.getLastRow();
  
  return numberOfRows;
}

// This function gets the result for the searched keywords and returns them
function getResults(searchNumberOfRows, searchValues, searchColumnNumber) {
  for (i = 0; i < globalConst.ProductSheetNumberOfRows; i++) {
    for (j = 0; j < searchNumberOfRows; j++) {
      var index = globalConst.ProductSheetValues[i].toString().indexOf(searchValues[j].toString());
      
      if(index !== -1){
        globalConst.ResultSheet.getRange(i + 2, searchColumnNumber).setValue(searchValues[j]);
        break;
      }
    }
  }
}
Example of list of products:
56040206 2002 Dodge Ram Truck (Gas) 5.9L Plug & Play ECM PCM | 56040206AC
56040205 2002 Dodge Ram Truck (Gas) 5.9L Plug & Play ECM PCM | 56040205AC
56044477 2004 Jeep Wrangler 4.0L Plug & Play ECM PCM | 56044477AD
56044419 2004 Jeep Wrangler 4.0L Plug & Play ECM PCM | 56044419AF
Example of list of Models
Suburban
Tahoe
200
300
Wrangler
Ram Truck (Gas)
Result
200
200
200
200
What I want
Ram Truck (Gas)
Ram Truck (Gas)
Wrangler
Wrangler

I don't want "200" to be considered as a match with for example "2004"

  • I have to apologize for my poor English skill. Unfortunately, I cannot understand the logic for achieving your goal. Can I ask you about the detail of your current issue and your goal? – Tanaike Nov 28 '22 at 00:28
  • I am comparing a list of keywords "Suburban, Tahoe, 200, 300, Wrangler, Ram Truck (Gas)" one by one to a group of strings which are my product titles. The goal is to find out if any of the keywords is in the product title or not but I don't want "200" to be matched with "2004" if that makes sense. – Alireza Mehrnia Nov 28 '22 at 00:42
  • Thank you for replying. I would like to support you. But, I have to apologize for my poor English skill, again. Unfortunately, I cannot still understand the logic for achieving your goal of `What I want`. But I would like to try to understand it. When I could correctly understand it, I would like to think of a solution. I would be grateful if you can forgive my poor English skill. – Tanaike Nov 28 '22 at 00:51
  • When the list of keywords "Suburban, Tahoe, 200, 300, Wrangler, Ram Truck (Gas)" are searched in the product title "56040206 2002 Dodge Ram Truck (Gas) 5.9L Plug & Play ECM PCM | 56040206AC" I want the result to be "Ram Truck (Gas)" and not "200". Currently the app matches "200" with "2002" and it returns the result as "200". I hope this clarifies the issue. – Alireza Mehrnia Nov 28 '22 at 01:03
  • @Tanaike Another example; Let's say I have a list of products "apple, watermelon, melon" and a keyword "melon" I want the search result when searching "melon" in the product list to be false, false, true – Alireza Mehrnia Nov 28 '22 at 01:21
  • If only to reply this part ```I have a list of products "apple, watermelon, melon" and a keyword "melon" I want the search result when searching "melon" in the product list to be false, false, true```, that is easy: ```['apple','watermelon','melon'].map(product => porduct === 'melon')``` should return result as ```[false,false,true]``` as you wish. – Ping Nov 28 '22 at 02:34
  • and I have no idea why do you have to make that ```globalConst``` object and do all those get and delete with the spreadsheet and sheet objects... is that somthing related with performence? It seems not necessary over-complicating things. – Ping Nov 28 '22 at 02:38
  • @ping Thanks for your response, now allow me to improve my example; what if my list of products are "red apple for $2.00, ripe watermelon for $10.00, green melon for $5.00" and my search keyword is "melon" and I am expecting [false,false,true] as a result. – Alireza Mehrnia Nov 28 '22 at 02:58
  • @ping I have many other functions using the values from "globalConst". This code is just a small part of it. – Alireza Mehrnia Nov 28 '22 at 03:11
  • what you means by ```my list of products```, is it plain string? an array? or something etc? – Ping Nov 28 '22 at 03:31
  • in case that are an array with each array value holding a string of sentence, do you have commond structure on these string sentence? like, if they are always structured as the sample you gave, which is: ```color``` ```type``` ```"for"``` ```price```, in that case, you can work with them easily with a split method as: ```value.split(' ')``` which result in an array containing each of the string seperated by a ' ' (space), such as ```'red apple for $2.00'.split(' ')``` has a return value of ```['red','apple','for','$2.00']```, than you will be able to work with it with other array methods. – Ping Nov 28 '22 at 03:37
  • I will put down a sample in reply, this is too long to mention in comments. – Ping Nov 28 '22 at 03:39
  • list of products is basically 5645 rows of product names that I am reading them from "Product" sheet The keywords are about 240 and I am reading them from "Model" sheet They are stored in 2 different arrays ProductSheetValues and modelSheetValues In the next step I am trying to compare modelSheetValues[0]...modelSheetValues[239] one by one with each of the product values ProductSheetValues [0]...[ProductSheetValues[5644] to find out if the keyword is in the product name or not. – Alireza Mehrnia Nov 28 '22 at 03:47
  • see if my reply answer your requirment. – Ping Nov 28 '22 at 03:52
  • Thank you for replying. I understood your question. Now, I noticed that the discussions have advanced. In this case, I would like to respect the existing answer. – Tanaike Nov 28 '22 at 04:05

1 Answers1

0

Here is an example on how you can work this out:

// in case you have all data in plain text:
const input = "red apple for $2.00, ripe watermelon for $10.00, green melon for $5.00";

// you can split them in porducts:
const products = input.split(', ');

// check how it looks like now:
console.log(products);
/** output:
[
  "red apple for $2.00",
  "ripe watermelon for $10.00",
  "green melon for $5.00"
]
*/

// than, iterate this array again with .map method to break it down once again:
const productBrokenDown = products.map(product => product.split(' '));

// check how it looks like now:
console.log(productBrokenDown);
/** output:
[
  ["red","apple","for","$2.00"],
  ["ripe","watermelon","for","$10.00"],
  ["green","melon","for","$5.00"]
]
*/

// as you can see, the values becomes a 2D array which each row contains an array of values, which matches a patten [Color,FruitType,"for",Price], which we can now check the 'FruitType' of each row to return the true / false result you expected:

const results = productBrokenDown.map(row => row[1] === 'melon');

// check the results:
console.log(results);
/** output:
[
  false,
  false,
  true
]
*/
Ping
  • 891
  • 1
  • 2
  • 10