数组公式 return 没有重复的 ARRAY,没有 VBA

Array formula to return an ARRAY without duplicates, without VBA

我想知道是否可以 return 来自单个单元格公式的数组,该公式经过过滤以删除重复项,并且完全基于 Excel 公式构建。

我知道 return 一个 list 值的方法,其中删除了重复项(参见 this question),其中列表分布在多个单元格上。但是我特别想要 return 一个中间数组。

例如对于 A1:A5 中的列表,我可以获得值数组 {0.1,0.2,0.2,0.7,0.3},我希望从中获得第二个数组 {0.1,0.2,0.7,0.3} 作为数组公式的中间值。 Current approaches 使用单端锚定 运行ges(如 C:C1)以几何方式遍历数组中的项目(通过向下拖动 C 列)。我想在公式中不迭代数组。然后我可以像操作任何其他数组一样操作它。

如果可能,所有这些都应该在一个单元格中进行。

注意

两个 and 答案都完全有效,我 运行 对每个答案都进行了速度检查 - 差异可以忽略不计(任何差异都小于测试运行之间的差异)。两者都得分为 ~ 1.0±0.2 ms

使用此数组公式求和唯一值,它需要使用仅适用于 Office 365 的 TEXTJOIN() Excel:

=SUM( IF(ISERROR(FIND(TRIM(MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999+1,999)),MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),1,(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999))),--TRIM(MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999+1,999))))

数组公式需要在退出编辑模式时用Ctrl-Shift-Enter确认,而不是Enter。

您可以用许多不同的公式替换 SUM。

如果没有 Office 365 Excel,那么 vba 和/或辅助列是唯一可用的方法。


编辑:

要从数组中删除 False 和 return 数组中的第 3 个非重复项,我们可以将其包装在另一个 TEXTJOIN 中:

=--TRIM(MID(TEXTJOIN(REPT(" ",999),TRUE,IF(ISERROR(FIND(TRIM(MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999+1,999)),MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),1,(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999))),--TRIM(MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999+1,999)),"")),(3-1)*999,999))

(3-1)*999 中的 3 可以替换为 return 所需索引号的任何内容。

仍然是数组公式,需要Ctrl-Shift-Enter。

如果你想return中的相对位置然后使用这个数组:

=AGGREGATE(15,6,ROW(INDIRECT("1:" & COUNTA(A:A)))/(--TRIM(MID(TEXTJOIN(REPT(" ",999),TRUE,IF(ISERROR(FIND(TRIM(MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999+1,999)),MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),1,(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999))),--TRIM(MID(TEXTJOIN(REPT(" ",999),TRUE,A:A),(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999+1,999)),"")),(ROW(INDIRECT("1:" & COUNTA(A:A)))-1)*999,999))=B1),1)


我给了你创建数组的长公式,但求和:

=SUMPRODUCT(A1:A5/COUNTIF(A1:A5,A1:A5)) 

就足够了。

对于平均值:

=SUMPRODUCT(A1:A5/COUNTIF(A1:A5,A1:A5))/SUMPRODUCT(1/COUNTIF(A1:A5,A1:A5))

如果您知道自己想要什么,有许多更短更好的解决方法。

此公式将 return 一个没有重复项的排序数组,例如举个例子

{0.1;0.2;0.3;0.7}

=SMALL(IF(MATCH(A1:A5,A1:A5,0)=ROW(A1:A5)-ROW(A1)+1,A1:A5),ROW(INDIRECT("1:"&SUM(0+(0<(FREQUENCY(A1:A5,A1:A5)))))))

通过 CTRL+SHIFT+ENTER

确认

......或此版本保持顺序

=INDEX(A1:A5,N(IF({1},SMALL(IF(MATCH(A1:A5,A1:A5,0)=ROW(A1:A5)-ROW(A1)+1,ROW(A1:A5)-ROW(A1)+1),ROW(INDIRECT("1:"&SUM(0+(0<(FREQUENCY(A1:A5,A1:A5))))))))))

我为范围 (A1:A5) 使用了定义的名称并将其命名为 myList。您可以这样做,或者如果您愿意,可以在地址 $A$1:$A$5 中替换:

{=INDEX(myList, N(IF({1}, MODE.MULT(IF(MATCH(myList, myList, 0) = ROW(myList), ROW(myList)*{1,1})))), 1)}

编辑: 如果列列表在 sheet 的下方,并且由 OP 提供的更短的 minrow 例程,则上面的处理不稳健:

{=INDEX(myList, N(IF({1}, MODE.MULT(IF(MATCH(myList, myList, 0)=ROW(myList)-MIN(ROW(myList))+1, (ROW(myList)-MIN(ROW(myList))+1)*{1,1})))), 1)}

这对你来说应该没问题。不用说了,这些都是数组公式..