【问题标题】:Determine if a row of strings exists in multiple rows of string判断多行字符串中是否存在一行字符串
【发布时间】:2021-10-03 04:40:35
【问题描述】:

我有一个歌曲列表。每首歌曲都有一个演奏该歌曲所需所有人的名单。

例如

Song1 | Jess | Julia | Mandy | Fred | Simon | 
Song2 | Jess | Julia |       | Fred | Simon |
Song3 |      | Julia |       | Fred | Simon |

然后我有一个在场人员的列表。

例如

Jess | Julia | Fred | Simon 

我想将出现的人员列表与歌曲列表进行比较,以便我们知道可以演奏哪些歌曲。

如果我们比较这两个示例,我们知道可以执行 Song2 和 Song3 但不能执行 Song1。 Song2 因为 Jess、Julia、Fred 和 Simon 在场。 Song3 因为 Julia、Fred、Simon 在场(Jess 在场但不需要)。 由于 Mandy 不存在,因此不应返回 Song1。

我希望返回第一列中的歌曲名称。

到目前为止,我有类似的东西,但我知道它不对:

=IF(REGEXMATCH(A1:1, B2:E2), A2, "Nope")

其中 A1:1 是在场人员所在的行,B2:E2 是演唱歌曲所需的人员。 A2 是歌曲的标题。

我最初尝试过:

=IF(A1:1=B2:E2, A2, "Nope")

但知道这是行不通的,因为它正在比较精确匹配。

谢谢。

编辑:

如果我把它写成代码,它可能是这样的。

const presentSingers = ['Julia', 'Mandy', 'Jess', 'Fred']
const song1 = ['Julia', 'Mandy']
const song2 = ['Julia', 'Mandy', 'Jess', 'Fred']
const song3 = ['Julia', 'Rachel', 'Mandy']
const allSongs = [song1, song2, song3]

const songsThatCanBePerformed = []

allSongs.forEach((song) => {
   let present = true
   song.forEach((singer) => {
      if (!singers.includes(singer)) {
         present = false
      }
   })
   if (present) {
      songsThatCanBePerformed.push(song)
   }
})

console.log(songsThatCanBePerformed)

【问题讨论】:

  • 只有几个歌手(如示例中所示)还是可能的歌手列表很长?如果是的话,现在 lobg?
  • 目前的表演者名单会有 10 到 16 个不同的名字。每首歌曲将有 10 到 16 位不同的表演者。
  • vb 解决方案是否可行(尽管您有 google sheet 标签)?
  • 感谢您的回复。实际上,Google Sheets 也支持脚本,这让我记忆犹新。我能够解决我的问题。
  • 嗯...好的。当时我还在考虑解决方案“可能”需要多么花哨和适应性强。但后来我发现这可以通过一个公式来完成,该公式实际上可以适应数据结构中可能发生的变化(见下文)。

标签: google-apps-script google-sheets google-sheets-formula formula


【解决方案1】:

你可以使用这个公式

=if(average(countif(F4:J4,vlookup(F4,N4:N7,1,false)),countif(F4:J4,vlookup(G4,N4:N7,1,false)),countif(F4:J4,vlookup(H4,N4:N7,1,false)),countif(F4:J4,vlookup(I4,N4:N7,1,false)),countif(F4:J4,vlookup(J4,N4:N7,1,false)))<1,"Cannot Perform","Can Perform")

在哪里

F4:J4 = 代表需要的执行者

H4:N7 = 代表表演者的出席率

简而言之,如果表演者在场,则此公式的工作原理是返回 1 并获得出勤率的平均值,每个人都在场则平均值为 1,否则小于 1。

如果您不想完全匹配,则可以在 vlookup 搜索中使用通配符。

【讨论】:

    【解决方案2】:

    Google 表格支持一种脚本语言,可让您编写“类似 JavaScript”的代码。

    More can be found about Google App Script here

    像这样从工作表中获取成员。

    const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
    
    // Get the members sheet
    const membersSheet = spreadsheet.getSheetByName(membersSheetTitle);
    const membersData = membersSheet.getDataRange().getValues();
    

    可以以类似的方式检索歌曲。

    现在,像这样进行计算。

      const songsThatCanBePerformed = [];
      allSongs.forEach((song) => {
        let present = true;  
        for (let i = 1; i <= song.length; i++) {
          const singer = song[i];
          if (singer && !presentSingers.includes(singer)) {
            present = false;
          }
        }
    
        // Add just the song title to the list.
        if (present && song[songTitleIndex]) {
          songsThatCanBePerformed.push([song[songTitleIndex]]);
        }
      });
    
      if (songsThatCanBePerformed.length === 0) {
        return;
      }
    

    可以使用以下命令将结果输入到工作表中。

      // Set where the data should be written
      const startRow = 2;
      const startCol = 7;
      const numRows = songsThatCanBePerformed.length;
      const numCols = 1;
      const range = membersSheet.getRange(startRow, startCol, numRows, numCols);
      range.clearContent();
      // write the results
      range.setValues(songsThatCanBePerformed);
    

    【讨论】:

      【解决方案3】:

      您可以尝试以下方法:

      H1中的公式:

      =FILTER(A1:A3,MMULT(ISNA(MATCH(B1:F3,J1:M1,0))*(B1:F3<>""),SEQUENCE(5,1,1,0))=0)
      

      【讨论】:

        【解决方案4】:

        这里的东西非常简单,但适应性强,(到目前为止,我能想到的最简单的东西可以完全解决所描述的功能):

        Using B2 as helper cell to concatenate the "artists present" list 
        {=IF(SUM(IF(B5:H5<>"",IF(ISERROR(FIND(B5:H5,$B$2)),0,1)))=COUNTA(B5:H5),"Yes","Nope")}
        

        注意 {}:这是一个数组公式。

        象形图:

        附加信息:
        以上是相当动态的,因为它支持不连续的艺术家姓名输入(在那些存在的列表中,以及每首歌曲旁边的列表中)。也就是说,即使艺术家姓名之间有空单元格,它仍然可以工作。

        它还允许(例如)将艺术家姓名放在两行或多行而不是 1 行中。以防万一(例如)您更喜欢更窄的查看窗口。

        如果您决定将艺术家姓名放在列中而不是行中,它也同样有效,无论是“那些出席者”列表或歌曲 - 艺术家列表或两者。

        使用分隔符:
        为了增加另一个级别的完整性,您可以在 Artists Present 的串联中包含分隔符(以防出现奇怪的情况,例如 'Simone' + 'Mal' 匹配 Ema)。

        【讨论】:

        • 供参考:我已经在谷歌表格中确认了上述作品
        【解决方案5】:

        试试这个公式:

        =AND(NOT(ISNA(HLOOKUP(B2:INDEX(B2:F2,COUNTA(B2:F2)),$A$7:$D$7,1,FALSE))))
        
        • Formula 将返回歌手姓名或#N/A 的数组,具体取决于在歌曲要求中查找名称
        • B2:INDEX(B2:F2,COUNTA(B2:F2)) 确保我们的数据中不包含空白。
          • 假定名称从左到右按顺序列出,中间没有空单元格。
          • 如果不是这样,可以设计一个更复杂的公式。
        • NOT(ISNA(... 将其更改为布尔数组
        • AND 确保数组中的每个元素都是 TRUE 以便可以执行测试 TRUE

        注意:在早期版本的 Excel 和 Google 表格中,这必须作为数组公式输入;在 Excel 中使用 ctrl+shift+enter 或在表格中使用 =ArrayFormula(...

        如果艺术家姓名不连续

        =AND(NOT(ISNA(HLOOKUP(FILTER(B2:F2,B2:F2<>""),$A$7:$D$7,1,FALSE))))
        

        可用于 Office 365 和 Google 表格(使用 ArrayFormula(...。不过,早期版本的 Excel 没有 FILTER 函数。

        【讨论】:

        • 呃...这不起作用。您可以通过查看自己的结果来判断。
        • @Spinner 你是对的,我的逻辑倒退了。会编辑。 Tks
        • Erm...根据您的图像,您似乎更改了那里的结果,但上面的实际公式仍然不起作用。
        • @Spinner 在这里工作正常。我编辑了屏幕截图以显示输入的公式。你得到什么样的结果?
        • 嗯。事实证明,如果作为动态数组输入(即不使用 Ctrl、Shift、Enter),它几乎可以工作。但不能作为“传统”数组公式。除此之外,它仍然并不总是有效,因为它不能满足歌手名字中的空白。即,即使所有歌手都在场,它也会产生 FALSE,但给定歌曲的名称不在连续的单元格中,从左到右。您可能会在作者的示例中注意到,名称可能是不连续的。这是我专注于正确的功能之一。并由我在回答中建议的公式解决。 :)
        猜你喜欢
        • 2013-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-26
        • 2011-02-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多