合并重复项并对值求和 - 在单个字符串/单元格内

use*_*253 10 google-sheets google-sheets-formula

我将此字符串放在一个单元格 (A1) 中:

\n
Apple \xe2\x80\x93 1\nBanana \xe2\x80\x93 6\nCherry \xe2\x80\x93 10\nPeach \xe2\x80\x93 100\nApple \xe2\x80\x93 1000\nKiwi \xe2\x80\x93 10999\nPeach \xe2\x80\x93 44\nFig \xe2\x80\x93 3/100\nFig \xe2\x80\x93 3/100\n
Run Code Online (Sandbox Code Playgroud)\n

我需要找到一个可以组合重复条目并对它们的值求和的公式。因此,所需的输出是这样的(也在单个单元格中,比如说 B1):

\n
Apple \xe2\x80\x93 1001\nBanana \xe2\x80\x93 6\nCherry \xe2\x80\x93 10\nPeach \xe2\x80\x93 144\nKiwi \xe2\x80\x93 10999\nFig \xe2\x80\x93 6/100\n
Run Code Online (Sandbox Code Playgroud)\n

我尝试了几个小时,但不知道该怎么做。我尝试的是首先找到独特的价值。到目前为止,没有问题:

\n
=UNIQUE(\n    ARRAYFORMULA(\n        REGEXEXTRACT(\n            TRANSPOSE(SPLIT(A1, CHAR(10))),\n            "(.*) \xe2\x80\x93 [0-9.]+/?[0-9]?"\n        )\n    )\n)\n
Run Code Online (Sandbox Code Playgroud)\n

返回唯一值的数组

\n
{"Apple", "Banana", "Cherry", "Peach", "Kiwi", "Fig"}\n
Run Code Online (Sandbox Code Playgroud)\n

我能想到的最好结果是这个公式,手动使用 Apple 和 Banana:

\n
=ARRAYFORMULA(\n    {\n        "Apple" & " \xe2\x80\x93 " & SUM(\n            ARRAYFORMULA(\n                IF(\n                    REGEXMATCH(\n                        TRANSPOSE(SPLIT(A1, CHAR(10))),\n                        "Apple" & " \xe2\x80\x93 [0-9.]+/?[0-9]?"\n                    ),\n                    VALUE(\n                        REGEXEXTRACT(\n                            TRANSPOSE(SPLIT(A1, CHAR(10))),\n                            "Apple \xe2\x80\x93 ([0-9.]+)/?[0-9]?"\n                        )\n                    ),\n                    ""\n                )\n            )\n        );\n        "Banana" & " \xe2\x80\x93 " & SUM(\n            ARRAYFORMULA(\n                IF(\n                    REGEXMATCH(\n                        TRANSPOSE(SPLIT(A1, CHAR(10))),\n                        "Banana" & " \xe2\x80\x93 [0-9.]+/?[0-9]?"\n                    ),\n                    VALUE(\n                        REGEXEXTRACT(\n                            TRANSPOSE(SPLIT(A1, CHAR(10))),\n                            "Banana \xe2\x80\x93 ([0-9.]+)/?[0-9]?"\n                        )\n                    ),\n                    ""\n                )\n            )\n        )\n    }\n)\n
Run Code Online (Sandbox Code Playgroud)\n

这正确地输出了数组

\n
{"Apple \xe2\x80\x93 1001", "Banana \xe2\x80\x93 6"}\n
Run Code Online (Sandbox Code Playgroud)\n

但无论我如何尝试,我都无法让它针对所有独特元素动态工作。我觉得我已经解决了难题的两部分,但我就是无法将它们组合在一起

\n

z..*_*z.. 6

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

\n
=ARRAYFORMULA(\n  LET(data,WRAPROWS(SUBSTITUTE(SPLIT(SUBSTITUTE(A1,"/","\xce\xb6")," \xe2\x80\x93"&CHAR(10)),"\xce\xb6","/"),2),\n      items,INDEX(data,,1),\n      qty,MAP(INDEX(data,,2),LAMBDA(n,SORTN(QUERY(,"select "&n)))),\n      JOIN(CHAR(10),MAP(UNIQUE(items),LAMBDA(item,item&" \xe2\x80\x93 "&SUM((item=items)*qty))))))\n
Run Code Online (Sandbox Code Playgroud)\n

在此输入图像描述

\n

data数组以我们可以使用的方式格式化数据:

\n
WRAPROWS(SUBSTITUTE(SPLIT(SUBSTITUTE(A1,"/","\xce\xb6")," \xe2\x80\x93"&CHAR(10)),"\xce\xb6","/"),2)\n
Run Code Online (Sandbox Code Playgroud)\n

qty数组将数字转换为其非小数表示形式:

\n
MAP(INDEX(data,,2),LAMBDA(n,SORTN(QUERY(,"select "&n))))\n
Run Code Online (Sandbox Code Playgroud)\n

然后我们使用以下函数迭代每个独特的水果MAP

\n
MAP(UNIQUE(items),LAMBDA(item,\n
Run Code Online (Sandbox Code Playgroud)\n

对于每个水果,我们执行一个条件求和,其中标准范围是所有水果的数组,标准是当前水果,总和范围是与每个水果相关的数量数组:

\n
SUM((item=items)*qty)\n
Run Code Online (Sandbox Code Playgroud)\n

最后,我们将所有内容结合在一起:

\n
JOIN(CHAR(10),...)\n
Run Code Online (Sandbox Code Playgroud)\n

分数量的替代表示

\n

约化分数

\n
=ARRAYFORMULA(\n  LET(data,WRAPROWS(SUBSTITUTE(SPLIT(SUBSTITUTE(A1,"/","\xce\xb6")," \xe2\x80\x93"&CHAR(10)),"\xce\xb6","/"),2),\n      items,INDEX(data,,1),\n      qty,INDEX(data,,2),\n      JOIN(CHAR(10),\n        MAP(UNIQUE(items),LAMBDA(item,    \n          LET(qty_,FILTER(qty,items=item),\n              s,SPLIT(TOCOL(REGEXREPLACE(qty_,"^[^/]+$","$0/1")),"/"),\n              nums,INDEX(s,,1),dens,INDEX(s,,2),l,LCM(dens),nnum,SUM(l/dens*nums),g,GCD(nnum,l),\n              item&" \xe2\x80\x93 "&IF(COUNTIF(qty_,"*/*")=0,SUM(--qty_),nnum/g&"/"&l/g)))))))\n
Run Code Online (Sandbox Code Playgroud)\n

在此输入图像描述

\n

未约分数

\n
=ARRAYFORMULA(\n  LET(data,WRAPROWS(SUBSTITUTE(SPLIT(SUBSTITUTE(A1,"/","\xce\xb6")," \xe2\x80\x93"&CHAR(10)),"\xce\xb6","/"),2),\n      items,INDEX(data,,1),\n      qty,INDEX(data,,2),\n      JOIN(CHAR(10),\n        MAP(UNIQUE(items),LAMBDA(item,    \n          LET(qty_,FILTER(qty,items=item),\n              s,SPLIT(TOCOL(REGEXREPLACE(qty_,"^[^/]+$","$0/1")),"/"),\n              nums,INDEX(s,,1),dens,INDEX(s,,2),l,LCM(dens),\n              item&" \xe2\x80\x93 "&IF(COUNTIF(qty_,"*/*")=0,SUM(--qty_),SUM(l/dens*nums)&"/"&l)))))))\n
Run Code Online (Sandbox Code Playgroud)\n

在此输入图像描述

\n

  • 惊人的!但是,当我们向菜单添加包含空格的项目时,似乎存在问题,例如我们向菜单添加“Apple Pie – 8”。我能够通过从 SPLIT 参数中删除空格并添加 TRIM 来解决此问题: `WRAPROWS(TRIM(SUBSTITUTE(SPLIT(SUBSTITUTE(B2,"/","ze"),"–"&CHAR(10)) ,"z","/")),2)` (2认同)