我在A栏中有一个长词,如'谴责'和'收入',以及B栏中的'Con'和'Come'等短词。
我想在右边创建一个单元格,如果它包含“SHORTER WORD”列的文本并将它们打印成一对,将搜索“LONG WORD”列。
我只需要它返回它遇到的第一个实例。
我已经查看了各种MATCH和LOOKUP命令,但似乎没有人能够“从整列中返回一个匹配的单词”。
由于
塔迪
答案 0 :(得分:1)
我已经为你整理了一个基于脚本的解决方案。其他解决方案需要在您可能有部分的每一行上都有一个公式,最终会导致大量数据集陷入困境。这应该在几秒钟之后为数据行数万行生成一系列匹配。
注意:由于您选择不提供样本数据集,因此我不得不假设它是如何布局的。但是,无论您的列位于何处,只要标题为Full Words
,Partials
和Matches
,这都可以使用。
链接到电子表格(必须登录Google帐户才能使用该按钮):Google Sheet
只需点击Get Matches
按钮即可生成匹配项。
源代码比它需要的更复杂/更动态,但我已经有一堆功能已经存在,我只是重复使用。
<强>来源:强>
//Retrieves all the necessary word matches
function GetWordMatches() {
var spreadsheet = SpreadsheetApp.openById('1s0S2iJ7L0wEXgVsKrpuK-aLysaxfHYRDQgp3ShPR8Ns').getSheetByName('Matches');
var dataRange = spreadsheet.getDataRange();
var valuesRange = dataRange.getValues();
var columns = GetColumns(valuesRange, dataRange.getNumColumns(), 0);
var fullWordsData = GetColumnAsArray(valuesRange, columns.columns['Full Words'].index, true, 1);
var partialsArray = GetColumnAsArray(valuesRange, columns.columns['Partials'].index, true, 1);
var partialsData = GeneratePartialsRegexArray(partialsArray);
var matches = GenerateMatches(fullWordsData, partialsData);
WriteMatchesToSheet(spreadsheet, columns.columns['Matches'].index, matches, partialsArray);
}
//Writes the matches to the sheet
function WriteMatchesToSheet(spreadsheet, matchesColumnIndex, matches, partialsArray){
var sortedMatches = SortByKeys(matches, partialsArray);
var dataRange = spreadsheet.getRange(2, matchesColumnIndex+1, sortedMatches.length);
dataRange.setValues(sortedMatches);
}
//Generates an array of matches for the full words and partials
function GenerateMatches(fullwordsData, partialsData){
var output = [];
var totalLoops = 0;
for(var i = 0; i < fullwordsData.length; i++){
totalLoops++;
for(var ii = 0; ii < partialsData.length; ii++){
totalLoops++;
var result = fullwordsData[i].match(partialsData[ii].regex)
if(result){
output.push([fullwordsData[i], partialsData[ii].value]);
partialsData.splice(ii, 1);
break;
}
}
}
if(partialsData.length > 0){
var missedData = GenerateMissedPartialsArray(partialsData);
output = output.concat(missedData);
}
return output;
}
//Generates a missed partials array based on the partials that found no match.
function GenerateMissedPartialsArray(partialsData){
var output = [];
for(var i = 0; i < partialsData.length; i++){
output.push(['No Match', partialsData[i].value])
}
return output;
}
//Generates the regex array for the partials
function GeneratePartialsRegexArray(partialsArray){
var output = [];
for(var i = 0; i < partialsArray.length; i++){
output.push({regex: new RegExp(partialsArray[i], 'i'), value: partialsArray[i]});
}
return output;
}
//http://stackoverflow.com/a/13305008/3547347
function SortByKeys(itemsArray, sortingArray){
var itemsMap = CreateItemsMap(itemsArray), result = [];
for (var i = 0; i < sortingArray.length; ++i) {
var key = sortingArray[i];
result.push([itemsMap[key].shift()]);
}
return result;
}
//http://stackoverflow.com/a/13305008/3547347
function CreateItemsMap(itemsArray) {
var itemsMap = {};
for (var i = 0, item; (item = itemsArray[i]); ++i) {
(itemsMap[item[1]] || (itemsMap[item[1]] = [])).push(item[0]);
}
return itemsMap;
}
//Gets a column of data as an array
function GetColumnAsArray(valuesRange, columnIndex, ignoreBlank, startRowIndex){
var output = [];
for(var i = startRowIndex; i < valuesRange.length; i++){
if(ignoreBlank){
if(valuesRange[i][columnIndex] !== ''){
output.push(valuesRange[i][columnIndex]);
}
continue;
}
output.push(valuesRange[i][columnIndex]);
}
return output;
}
//Gets a columns object for the sheet for easy indexing
function GetColumns(valuesRange, columnCount, rowIndex)
{
var columns = {
columns: {},
length: 0
}
Logger.log("Populating columns...");
for(var i = 0; i < columnCount; i++)
{
if(valuesRange[0][i] !== ''){
columns.columns[valuesRange[0][i]] = {index: i ,value: valuesRange[0][i]};
columns.length++;
}
}
return columns;
}
关于某些决定的说明:为了提高性能,我选择不使用map
或其他更简洁的数组函数。
答案 1 :(得分:0)
MATCH和LOOKUP不适用于部分匹配。
另一种方法是将SEARCH或FIND与数组公式中的其他函数一起使用。
示例:
=ArrayFormula(INDEX(A1:A,SORT(IF(search(B1,A1:A),ROW(A1:A),),1,TRUE)))
数据
+---+--------------+-------+-------------+ | | A | B | C | +---+--------------+-------+-------------+ | 1 | Orange juice | apple | Apple cider | | 2 | Apple cider | | | | 3 | Apple pay | | | +---+--------------+-------+-------------+
答案 2 :(得分:0)
好的,我想我已经找到了答案。我会在这里发布,以防其他人使用它。
为了给予应有的信用,found it here
这就是我想要的:
=INDEX($D$1:$D$3,MATCH(1,COUNTIF(A1,"*"&$D$1:$D$3&"*"),0))
它确实减慢了一切,因为一切都像疯了一样交叉引用(我的电子表格上有3000行)但是如果在D1-3中有一个单词列表,它将看到单元格A1是否包含一个这些单词并打印出与之匹配的单词。
感谢所有提供解决方案的人,特别是@ douglasg14b - 如果有一个在内存方面不那么重要的话,那就太棒了,但这样做的方式很慢!
由于
塔迪
答案 3 :(得分:0)
这也有效:
=QUERY(FILTER($D$1:$D$3,REGEXMATCH(A1,"(?i)"&$D$1:$D$3)),"limit 1")
我们使用REGEXMATCH
和(?i)
使搜索不区分大小写。查询中的limit 1
仅提供第一次出现。