神秘的使用LOOKUP
我一直在使用这个Excel公式多年。 它工作正常,但我想明白为什么它的作品! 该公式用于查找列表中最后一个关联的值。 例如:
公式C14: =LOOKUP(2,1/(B1:B12="meat"),C1:C12)
这里, C14
的公式在B列中查找最新的"meat"
标记的单元格,并返回C列中的相关值。 它在B9
find"meat"
,并相应地返回C9
的值。
公式中最令人费解的部分是"1/(....)"
。 这个部门是什么? 这个语法来自哪里? 它可以用在其他地方吗? 为什么查找值2
?
这是发生了什么:这个
=LOOKUP(2,1/(B1:B12="meat"),C1:C12)
变成这个
=LOOKUP(2,1/{TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;FALSE;FALSE;FALSE},C1:C12)
这变成了这个
=LOOKUP(2,{1;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!;#DIV/0!;1;#DIV/0!;#DIV/0!;#DIV/0!},C1:C12)
B1:B12="meat"
部分被评估为TRUE和FALSE值的数组。 当你对TRUE或FALSE进行math运算时,它将变成1或0.将1除以1或0将返回1,对于所有的结果返回1,对于所有的假设返回div / 0。
现在你知道你将有一个正好两个东西(一个1或一个div / 0)的数组,你可以查找任何大于1的数字,它将返回列表中的最后一个数字。 你可以=LOOKUP(800,...)
,它仍然会返回“小于或等于查找值的最大值”,或者在你的情况1。
所以这两个有点武断 – 它只是一个大于1的数字。关键是创build仅包含1和错误的查找数组参数–LOOKUP忽略错误。
二进制search
我没有这方面的官方文档,所以这里是非官方的版本。 如果数据被sorting,LOOKUP,HLOOKUP和VLOOKUP就有一个参数来告诉函数。 如果该参数是False,则该函数一直查看每个条目直到结束。 如果该参数为True或省略,则该函数使用二进制search。 它是这样做的 – 这个论点只存在 – 因为二进制search比ol一次一个search要快。
二分search通过find中间值并根据所寻求的值对其进行评估而起作用。 如果中间值较大,则放弃右侧的所有内容 – search值必须在左侧。 它取左边的一半,find它的中间值。 如果它更大,则丢弃右边并保持左边。 继续迭代,直到find值。
那么,为什么LOOKUP(2,{1,1,#DIV/0!,1,1,#DIV/0!,1,1},...)
find最后的1
而不是一些任意的1
? 我不知道MS如何实现他们的二进制search,所以我必须做一些假设。 我的假设是错误值抛出数组,并且当有偶数个条目(没有中间值)时,使用中间左侧的值。 这些假设可能是错误的,但对结果没有影响。
首先,抛出错误。 现在你有这些条目和他们原来的位置
1 1 1 1 1 1 1 2 4 5 7 8
“中间”数字是1(4)。 它小于2(所寻求的价值),所以我们把所有东西扔到左边,重新处理右边。 现在我们有了
1 1 1 5 7 8
中间值是1(7)。 它不到2,所以我们把所有东西扔到左边,重新处理右边。 现在我们有了
1 8
我们只有一个入口,所以这就是答案。 如果查找的值高于所有其他值,则二分查找将始终返回最后一个值。
逻辑是这样的:
-
B1:B12="meat"
返回一组布尔值,TRUE其中“肉”,否则为FALSE - 1 / TRUE返回1,而1 / FALSE = 1/0返回#DIV / 0 !,所以你得到一个数组填充1和#DIV / 0!s,如下图所示。 (这一步用于将FALSE转换为错误值,供下一步使用。)
- 对该数组中的值2进行查找失败,因为在那里没有2,并且因为这些值是未分类的。 相反,LOOKUP会查找小于2的数值的最后一次出现,忽略任何#DIV / 0! 错误值。 为什么? 谁知道。 这是一个未logging的function, LOOKUPfunction的文档中没有提到
所以基本上,这个shenanigan依靠无证行为来返回所需的结果。