(Ответ здесь как отдельный вопрос для отсортированных данных.)
Если бы данные были отсортированы, вы могли бы использовать VLOOKUP
с range_lookup
аргументом TRUE
(или опустить, так как это по умолчанию), который официально описан для Excel как «поиск приблизительного соответствия».
Другими словами, для отсортированных данных:
- установка последнего аргумента для
FALSE
возврата первого значения и
- установка последнего аргумента
TRUE
возвращает последнее значение.
Это в значительной степени недокументировано и неясно, но относится к VisiCalc (1979), и на сегодняшний день действует по крайней мере в Microsoft Excel, LibreOffice Calc и Google Sheets. В конечном счете, это связано с первоначальной реализацией LOOKUP
в VisiCalc (а затем VLOOKUP
и HLOOKUP
), когда четвертого параметра не было. Значение определяется двоичным поиском с использованием включающей левой границы и исключительной правой границы (распространенная и элегантная реализация), что приводит к такому поведению.
Технически это означает, что поиск начинается с интервала-кандидата [0, n)
, где n
есть длина массива, а условие инварианта цикла состоит в том, что A[imin] <= key && key < A[imax]
(левая граница <= цель, правая граница, которая начинается одна после конца, равна > цель; для проверки либо проверять значения в конечных точках до, либо проверять результат после) и последовательно разбивать и выбирать любую сторону, сохраняющую этот инвариант: путем исключения одна сторона будет, пока вы не доберетесь до интервала с 1 членом [k, k+1)
, и алгоритм затем возвращает k
. Это не должно быть точное совпадение (!): Это просто самое близкое совпадение снизу. В случае дублирующих совпадений это приводит к возвращению последнего совпадения, так как требует, чтобы следующее значение было большечем ключ (или конец массива). В случае дубликатов вам нужно некоторое поведение, и это разумно и легко реализовать.
Это поведение явно указано в этой старой статье базы знаний Майкрософт (выделение добавлено): «XL: Как вернуть первое или последнее совпадение в массиве» ( Q214069 ):
Вы можете использовать функцию LOOKUP () для поиска значения в массиве отсортированных данных и возврата соответствующего значения, содержащегося в этой позиции, в другом массиве. Если значение поиска повторяется в массиве, оно возвращает последнее найденное совпадение . Такое поведение верно для функций VLOOKUP (), HLOOKUP () и LOOKUP ().
Официальная документация для некоторых таблиц приведена ниже; ни в одном из них не указано поведение «последнее совпадение», но оно подразумевается в документации Google Sheets:
Майкрософт Эксель
TRUE предполагает, что первый столбец в таблице отсортирован по номерам или по алфавиту, а затем будет искать ближайшее значение .
Google Sheets :
Если is_sorted
это TRUE
или опущено, возвращается ближайшее совпадение ( меньше или равно ключу поиска)