如何对excel / google工作表单元格进行迭代以获得成对组合?
"string1"
"string2"
"string3"
...
"string10"
我正在考虑编写一个可以迭代这些字符串的函数来创建以下内容:
"string1, string2"
"string1, string 3"
...
"string 1, string 10"
"string 2, string 3"
...
"string 2, string 10"
"string3, string 4"
... ...
"string9 string10".
这可以在谷歌表吗?
答案 0 :(得分:1)
本机功能是一项艰巨的任务。尝试使用脚本并将其用作自定义函数:
function getTournament(teams_from_range)
{
// teams_from_range -- 2D Array
var teams = [];
// convert to list
teams_from_range.forEach(function(row) { row.forEach(function(cell) { teams.push(cell); } ); } );
return getTournament_(teams);
}
function getTournament_(teams)
{
var start = 0;
var l = teams.length;
var result = [], game = [];
// loop each value
for (var i = 0; i < l; i++)
{
// loop each value minus current
start++;
for (var ii = start; ii < l; ii++)
{
game = []
game.push(teams[i]);
game.push(teams[ii]);
result.push(game);
}
}
return result;
}
用法:
=getTournament(A1:A10)
答案 1 :(得分:1)
我不得不同意@Max认为本机功能很难,或者至少是啰嗦,但可以在Google表格中使用
=ArrayFormula(query({if((row(A:A)<=counta(A:A)^2)*(int((row(A:A)-1)/counta(A:A))<mod((row(A:A)-1),counta(A:A))),
vlookup(int((row(A:A)-1)/counta(A:A)),{row(A:A)-1,A:A},2)&vlookup(mod((row(A:A)-1),counta(A:A)),{row(A:A)-1,A:A},2),"")},"select Col1 where Col1<>''"))
注1 - 方法
使用10个字符串的列表作为示例。
(1)使用
添加一列以对0到9之间的字符串进行编号{行(A:A)-1,A:A}
(2)使用VLOOKUP中的行号来获取该对的第一个字符串
VLOOKUP(INT((行(A:A)-1)/ COUNTA(A:A)),{行(A:A)-1,A:A},2)
Row number-1 int((row(A:A)-1)/counta(A:A)) String
0 0 String1
1 0 String1
...
9 0 String1
10 1 String2
...
20 2 String3
...
99 9 String10
(3)使用VLOOKUP中的行号来获取
对中的第二个字符串VLOOKUP(MOD((行(A:A)-1),COUNTA(A:A)),{行(A:A)-1,A:A},2)
Row number-1 mod((row(A:A)-1),counta(A:A)) String
0 0 String1
1 1 String2
2 2 String3
...
9 9 String10
10 0 String1
11 1 String2
...
99 9 String10
请注意,该列表将包含不需要的对,如String1String1和String2String1。
(4)使用if条件
将不需要的对设置为“”如果((行(A:A)LT = COUNTA(A:A)^ 2)*(INT((行(A:A)-1)/ COUNTA(A:A))
注1 按照@Max Makhrov的建议,使用过滤器删除不需要的对会更短。
(5)使用Query删除空行。
注2 - 行数限制
因为生成了冗余对然后被移除,所以这种方法要求N ^ 2行在片材中,其中N是字符串的数量而不是N *(N-1)/ 2,这是N的不同对的数量对象。相反,对于具有N行的薄片,可以这种方式处理的字符串s的最大数量是floor(sqrt(N)),例如,对于包含1,000行的工作表s = floor(sqrt(1000))= 31。
注3 - 避免生成冗余对的可能方法
可视化我尝试做的事情的一种方法如下,其中数组元素表示输出行(A:A),行和列标题指示相应的值,这些值用作查找以获取对象(字符串1) ,string 1),(string 1 string 2)等。
使用整数除法和MOD函数从输出行到查找值的映射相当容易。
我们真正想做的是获得像这样的非冗余对
但是那么如何从输出行1-10映射到查找值对1-5?
我希望通过一些数学提供(至少在原理上)一种方法来直接获得N(N-1)/ 2个非冗余对而不首先生成所有N ^ 2对,这是可能的。
上面三角形部分的行1到r中的单元的计数S是总计数N(N-1)/ 2减去它下面的行中的计数(Nr)(Nr-1)/ 2 < / p>
这可以重新安排如下
这是r中的二次方,所以我们可以使用常规公式
来解决它给予
因此,行由r。
的上述公式的上限给出r行末尾的数字(比如T)是用r的上限代替上面的第二个等式给出的
最后对应于S的列由
给出现在定义一个名为
的命名范围N.=counta(A:A)
和命名范围M,其值为
=2*N-1
然后最后你需要选择stringA(矩阵的行r)的公式是
=iferror(ArrayFormula(vlookup(ceiling((M-sqrt(M^2-8*row(A:A)))/2,1),{row(A:A),A:A},2)),"")
和选择stringB(矩阵的列c)所需的公式是
=iferror(ArrayFormula(vlookup(N+row(A:A)-(M*CEILING((M-SQRT(M^2-8*row(A:A)))/2,1)-CEILING((M-SQRT(M^2-8*row(A:A)))/2,1)^2)/2,{row(A:A),A:A},2)),"")
其中包含D和E列用于测试目的。
然后,如果需要,它只会将两个公式合并为一列。
答案 2 :(得分:0)
=QUERY(ARRAYFORMULA(SPLIT(
TRANSPOSE(SPLIT(REPT(CONCATENATE(A2:A&CHAR(9)), COUNTA(A2:A)), CHAR(9)))& " "&
TRANSPOSE(SPLIT(CONCATENATE(REPT(A2:A&CHAR(9), COUNTA(A2:A))), CHAR(9))), " ")),
"where Col1<>Col2 order by Col1", 0)
答案 3 :(得分:0)
=ARRAYFORMULA(SPLIT(SORT(
TRANSPOSE(SPLIT(CONCATENATE(REPT(UNIQUE(TRANSPOSE(SPLIT(JOIN(",",TEXTJOIN(",",1,A2:A)),",")))&","&
TRANSPOSE(UNIQUE(TRANSPOSE(SPLIT(JOIN(",",TEXTJOIN(",",1,A2:A)),",")))), (
UNIQUE(TRANSPOSE(SPLIT(JOIN(",",TEXTJOIN(",",1,A2:A)),",")))<=
TRANSPOSE(UNIQUE(TRANSPOSE(SPLIT(JOIN(",",TEXTJOIN(",",1,A2:A)),",")))))*
REGEXMATCH(CONCATENATE(","&SUBSTITUTE(TEXTJOIN(",",1,A2:A),",",",,")&","&CHAR(9)),"(,"&
UNIQUE(TRANSPOSE(SPLIT(JOIN(",",TEXTJOIN(",",1,A2:A)),",")))&",[^\t]*,"&
TRANSPOSE(UNIQUE(TRANSPOSE(SPLIT(JOIN(",",TEXTJOIN(",",1,A2:A)),","))))&",)|(,"&
TRANSPOSE(UNIQUE(TRANSPOSE(SPLIT(JOIN(",",TEXTJOIN(",",1,A2:A)),","))))&",[^\t]*,"&
UNIQUE(TRANSPOSE(SPLIT(JOIN(",",TEXTJOIN(",",1,A2:A)),",")))&",)"))&CHAR(9)),CHAR(9)))),","))