[英]How to filter array for only exact match in Google Apps Script/Javascript
I'm trying to use Google Apps Script to filter only exact matches.我正在尝试使用 Google Apps 脚本仅过滤完全匹配。 I've seen similar questions, but I can't seem to apply them to my situation.我见过类似的问题,但我似乎无法将它们应用于我的情况。
On one sheet, I have a table of information which has the item name in column A, its' ingredient in column B, and its' quantity in column C.在一张纸上,我有一个信息表,其中 A 列中的项目名称,B 列中的“成分”和 C 列中的“数量”。 Column A contains items named Test and Test 2. When I filter for Test 2, I get results of both Test and Test 2. Here is the code I'm using: A 列包含名为 Test 和 Test 2 的项目。当我过滤 Test 2 时,我得到了 Test 和 Test 2 的结果。这是我正在使用的代码:
var costSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Cost');
var ingSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Recipe Ingredient');
// Create list of items to filter from the full list
var rows = costSheet.getLastRow();
var itemList = costSheet.getRange(2, 1, rows - 1).getValues();
// Convert itemList to array to be used in filter
itemList = itemList.join();
// Get full non-filtered data
var fullList = ingSheet.getRange('A2:C514').getValues();
// Apply filter criteria
function checkMatch(item) {
return itemList.indexOf(item[0]) != -1;
}
filterList = fullList.filter(checkMatch);
// Clear target location, then place filtered data
costSheet.getRange('C2:E514').clearContent();
costSheet.getRange(2, 3, filterList.length, 3).setValues(filterList);
I don't have any trouble getting accurate results for multiple items from all three columns, and the only issue I have is when I try to filter an item that begins with the name of another item in the full list (eg filtering for Test 2 returns both Test and Test 2, when I want it to just return Test 2).我从所有三列中获得多个项目的准确结果没有任何问题,我遇到的唯一问题是当我尝试过滤以完整列表中另一个项目的名称开头的项目时(例如过滤测试 2当我希望它只返回测试 2 时,返回测试和测试 2)。
I am new to working with Google Apps Script/Javascript, hence the 'amateur' coding.我是使用 Google Apps Script/Javascript 的新手,因此是“业余”编码。
You are very close!你很亲近!
The issue is related to this line:该问题与此行有关:
itemList = itemList.join();
Assuming that itemList = [["Test 2"],["Test 3"]]
as a result of the getValues()
method.假设itemList = [["Test 2"],["Test 3"]]
作为getValues()
方法的结果。
If you apply join you are converting the above array into the following string
:如果您应用连接,则将上述数组转换为以下string
:
Test 1,Test 2
Therefore itemList.indexOf("Test")
will return 0
which means your filter function will evaluate to true
, but you don't want that since Test
is not part of your array.因此itemList.indexOf("Test")
将返回0
这意味着您的过滤器 function 将评估为true
,但您不希望这样,因为Test
不是您的数组的一部分。 You are mistakenly using the indexOf method of strings
instead of the indexOf method of arrays
.您错误地使用了strings
的indexOf方法,而不是arrays
的indexOf方法。
Having said that, your goal is to use the the indexOf method of arrays
.话虽如此,您的目标是使用arrays
的indexOf方法。 In order to do so, itemList
needs to be an array and not a string.为此, itemList
需要是一个数组而不是字符串。
To convert a 2D array [["Test 2"],["Test 3"]]
into a 1D array [Test 1, Test 2]
you can use flat .要将二维数组[["Test 2"],["Test 3"]]
转换为一维数组[Test 1, Test 2]
您可以使用flat 。
Change:改变:
itemList = itemList.join();
To:至:
itemList = itemList.flat();
Going for the extra mile, you can shorten your code and make it more JavaScript
modern like that:加倍努力,您可以缩短代码并使其更现代JavaScript
像这样:
function shorterFunction(){
const ss = SpreadsheetApp.getActiveSpreadsheet();
const costSheet = ss.getSheetByName('Cost');
const ingSheet = ss.getSheetByName('Recipe Ingredient');
const itemList = costSheet.getRange(2, 1, costSheet.getLastRow() - 1).getValues().flat();
const fullList = ingSheet.getRange('A2:C514').getValues();
const filterList = fullList.filter(r=>itemList.includes(r[0]))
costSheet.getRange('C2:E514').clearContent();
costSheet.getRange(2, 3, filterList.length, 3).setValues(filterList);
}
In this solution, I used an arrow function and includes .在此解决方案中,我使用了箭头 function并包含.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.