将 10 列单字数据合并为 3 列,每列最多 4 个字,带标点符号

问题描述 投票:0回答:1

目的:我尝试遵循三个准则,将 10 列名称合并为三列。 (如果有必要,我可能可以自己计算出标点符号,但不知道如何将其与此任务一步结合起来。)

  1. 在第一个单词之前和最后一个单词之后添加括号,并在名称之间添加逗号;

  2. 在进入下一列之前,每列最多添加四个单词(请注意下面第 3 条中的问题);

  3. 确保列之间的名称没有被破坏;这意味着一列中的第一个和最后一个不能跟在三个名称后面,因为这意味着五个单词。此中断必须在三个单词之后发生,并从第一个和最后一个单词开始下一列(请参阅所需输出中的第 5 行和第 6 行,以“Evan”和“Frank”开头)。

这是示例数据的图像:

这是所需输出的图像:

这里是数据链接: https://docs.google.com/spreadsheets/d/1rpZvxrBGPndRTmPq9ZXfOXm_XUbE23Uw0XabIqYnxqo/edit?usp=sharing

感谢您的浏览!

google-sheets formula
1个回答
0
投票

这是一个可能的解决方案:

=ARRAYFORMULA(
   LET(data,A2:O8,
       max_words,4,
       GET_COUNT,LAMBDA(str,COUNTA(SPLIT(str,", "))),
       first_last,REDUCE(TOROW(,1),SEQUENCE(COLUMNS(data)/3,1,1,3),
                    LAMBDA(acc,i,HSTACK(acc,BYROW(CHOOSECOLS(data,i,i+1,i+2),LAMBDA(names,TEXTJOIN(" ",1,names)))))),
       joined_first_last,BYROW(first_last,LAMBDA(names,TEXTJOIN(", ",1,names))),
       people,SPLIT(joined_first_last,", ",,),
       REDUCE(TOCOL(,1),SEQUENCE(ROWS(people)),
         LAMBDA(v_acc,i,IFNA(VSTACK(v_acc,
           LET(ans,TOROW(
                     REDUCE(,SEQUENCE(COUNTA(INDEX(people,i))),
                       LAMBDA(h_acc,j,
                          IF(j=1,INDEX(people,i,j),         
                            IF(GET_COUNT(INDEX(people,i,j))+GET_COUNT(CHOOSECOLS(h_acc,-1))<=max_words,
                              h_acc&IF(SEQUENCE(1,COLUMNS(h_acc))<COLUMNS(h_acc),,", "&INDEX(people,i,j)),
                              HSTACK(h_acc,INDEX(people,i,j)))))),3),
               cols,COLUMNS(ans),
               IF(cols=1,"("&ans&")",
                 IF(SEQUENCE(1,cols)=1,"("&ans&",",
                   IF(SEQUENCE(1,cols)=cols,ans&")",ans&","))))))))))

enter image description here

公式的第一部分是将数据转换为更可用的格式:

=ARRAYFORMULA(
   LET(data,A2:O8,
       max_words,4,
       GET_COUNT,LAMBDA(str,COUNTA(SPLIT(str,", "))),
       first_last,REDUCE(TOROW(,1),SEQUENCE(COLUMNS(data)/3,1,1,3),
                    LAMBDA(acc,i,HSTACK(acc,BYROW(CHOOSECOLS(data,i,i+1,i+2),LAMBDA(names,TEXTJOIN(" ",1,names)))))),
       joined_first_last,BYROW(first_last,LAMBDA(names,TEXTJOIN(", ",1,names))),
       people,SPLIT(joined_first_last,", ",,),
       people))

enter image description here

然后对于每一行,我们迭代每一列并应用以下算法:

  • 如果当前字符串中的单词数加上前一个字符串中的单词数小于或等于`max_words`,则将当前字符串追加到前一个字符串中,否则;
  • (如果当前字符串中的单词数加上前一个字符串中的单词数大于`max_words`)创建一个新字符串。
// if the count of the words in the current string plus the count of the words in the previous string is less than or equal to `max_words`

IF(GET_COUNT(INDEX(people,i,j))+GET_COUNT(CHOOSECOLS(h_acc,-1))<=max_words,

// append the current string to the previous string

   h_acc&IF(SEQUENCE(1,COLUMNS(h_acc))<COLUMNS(h_acc),,", "&INDEX(people,i,j)),

// otherwise, create a new string

   HSTACK(h_acc,INDEX(people,i,j))))
© www.soinside.com 2019 - 2024. All rights reserved.