Лабиринты программирования или PHP поиск по массивам
От автора: осень, зима, вот и потянуло меня на лирику да романтику. Вы думаете, программирование совсем не романтическое ремесло? Ошибаетесь! Взять хотя бы массивы. Их ветвление очень похожи на повороты лабиринтов, в которых незнающий человек может застрять навеки! Сегодня мы узнаем, как происходит в PHP поиск по массивам.
Массивы бывают разные…
Надеюсь, с массивами вы немного знакомы. Хотя не факт, поэтому пару «зарисовок» на тему :). Массивы бывают:
Простые – состоят из пары «ключ-значение», где в качестве ключа выступает значение индекса. Любой нумерованный список можно рассматривать как простой массив, в котором номер строки является индексом, а его содержание — значением.
Ассоциативные – в них ключами могут выступать не только числа, но и строки. Чаще всего ключ и значение логически (ассоциативно) связаны между собой. Пример такого массива я пока не придумал :).
Онлайн курс «PHP-разработчик»
Изучите курс и создайте полноценный проект — облачное хранилище файлов
С нуля освоите язык программирования PHP, структурируете имеющиеся знания, а эксперты помогут разобраться с трудными для понимания темами, попрактикуетесь на реальных задачах. Напишете первый проект для портфолио.
Одномерными – используется один индекс.
Многомерными – используется два и более индексов.
Получается, что массивы являются одной из самых простых разновидностей структурированного представления данных. Вся информация в них упорядочена с помощью ключей, а информация записана в значения элементов. Но как происходит поиск ключа в массиве PHP?
Спасибо функциям!
Большая и огромная человеческая благодарность всем функциям PHP, которые облегчают работу с массивами! Если бы их не было (функций), то сортировка данных превратилась бы в настоящую «пытку» головного мозга!
Ну, может я и приврал чуток :). Но объем кода без применения этих функций точно бы возрос в разы. Опять не верите? Тогда давайте докажу на примере.
У нас есть массив, состоящий из сотрудников. Нам нужно «поймать» Вольдемарыча. Для этого следует осуществить поиск элемента в массиве PHP по значению. Вот как будет выглядеть реализация данной задачи без применения специальных функций:
Получается, чтобы поймать Вольдемарыча, нам потребовалось запустить 10 строк кода. Теперь попробуем сделать то же самое с помощью функции array_search(). В качестве аргументов она принимает значение элемента и сам массив, а возвращает индекс (ключ) искомого. В нашем случае она возвратит ключ элемента с содержимым «Вольдемарыч».
Вот результат PHP поиска в массиве по значению:
Но почему функция вернула единицу, если Вольдемарыч у нас проходит «по списку» под номером два? Забыл сказать, что индексация массивов начинается не с 1, а с 0. Значит все верно.
«Многомерим» наш массив
В двух предыдущих примерах мы использовали одномерный массив, в котором для идентификации используется только один индекс. Но при работе со структурированными данными все элементы коллекций, списков, стеков и других «разновидностей» чаще всего взаимосвязаны между собой по нескольким «признакам».
Чтобы было понятнее, я предлагаю вспомнить о типах взаимосвязи между таблицами в одной базе данных. Например, существует таблица, в которую заносятся ФИО рабочих предприятия. При этом некоторые ее столбцы взаимосвязаны с другой таблицей, где фиксируется посещаемость (рабочий табель). А с этой таблицей может быть связана другая, куда (на основе табеля) вычисляется и заносятся сроки следующего (ежегодного) отпуска… То есть один элемент идентифицируется не по одному ключу, а по нескольким.
Получается, что PHP поиск в многомерном массиве осуществляется по двум и более индексам. Чтобы продемонстрировать это, нам придется немного подправить существующий вариант «структуры».
in_array
Ищет в haystack значение needle . Если strict не установлен, то при поиске будет использовано нестрогое сравнение.
Список параметров
Замечание:
Если needle — строка, сравнение будет произведено с учётом регистра.
Если третий параметр strict установлен в true , тогда функция in_array() также проверит соответствие типов параметра needle и соответствующего значения массива haystack .
Замечание:
До PHP 8.0.0 строковое значение параметра needle будет соответствовать значению массива 0 в нестрогом режиме, и наоборот. Это может привести к нежелательным результатам. Подобные крайние случаи существуют и для других типов. Если нет полной уверенности в типах значений, всегда используйте флаг strict , чтобы избежать неожиданного поведения.
Возвращаемые значения
Возвращает true , если needle был найден в массиве, и false в противном случае.
Примеры
Пример #1 Пример использования in_array()
$os = array( «Mac» , «NT» , «Irix» , «Linux» );
if ( in_array ( «Irix» , $os )) echo «Нашёл Irix» ;
>
if ( in_array ( «mac» , $os )) echo «Нашёл mac» ;
>
?>?php
Второго совпадения не будет, потому что in_array() регистрозависима, таким образом, программа выведет:
Пример #2 Пример использования in_array() с параметром strict
if ( in_array ( ‘12.4’ , $a , true )) echo «‘12.4’ найдено со строгой проверкой\n» ;
>
if ( in_array ( 1.13 , $a , true )) echo «1.13 найдено со строгой проверкой\n» ;
>
?>
Результат выполнения данного примера:
1.13 найдено со строгой проверкой
Пример #3 Пример использования in_array() с массивом в качестве параметра needle
if ( in_array (array( ‘p’ , ‘h’ ), $a )) echo «‘ph’ найдено\n» ;
>
if ( in_array (array( ‘f’ , ‘i’ ), $a )) echo «‘fi’ найдено\n» ;
>
if ( in_array ( ‘o’ , $a )) echo «‘o’ найдено\n» ;
>
?>
Результат выполнения данного примера:
Смотрите также
- array_search() — Осуществляет поиск данного значения в массиве и возвращает ключ первого найденного элемента в случае успешного выполнения
- isset() — Определяет, была ли установлена переменная значением, отличным от null
- array_key_exists() — Проверяет, присутствует ли в массиве указанный ключ или индекс
User Contributed Notes 8 notes
Loose checking returns some crazy, counter-intuitive results when used with certain arrays. It is completely correct behaviour, due to PHP’s leniency on variable types, but in «real-life» is almost useless.
The solution is to use the strict checking option.
$array = array(
‘egg’ => true ,
‘cheese’ => false ,
‘hair’ => 765 ,
‘goblins’ => null ,
‘ogres’ => ‘no ogres allowed in this array’
);
// Loose checking — return values are in comments
// First three make sense, last four do not
in_array ( null , $array ); // true
in_array ( false , $array ); // true
in_array ( 765 , $array ); // true
in_array ( 763 , $array ); // true
in_array ( ‘egg’ , $array ); // true
in_array ( ‘hhh’ , $array ); // true
in_array (array(), $array ); // true
in_array ( null , $array , true ); // true
in_array ( false , $array , true ); // true
in_array ( 765 , $array , true ); // true
in_array ( 763 , $array , true ); // false
in_array ( ‘egg’ , $array , true ); // false
in_array ( ‘hhh’ , $array , true ); // false
in_array (array(), $array , true ); // false
I got an unexpected behavior working with in_array. I’m using following code:
// .
$someId = getSomeId (); // it gets generated/fetched by another service, so I don’t know what value it will have. P.S.: it’s an integer
// The actual data in my edge-case scenario:
// $someId = 0;
// $anyArray = [‘dataOne’, ‘dataTwo’];
if ( in_array ( $someId , $anyArray )) // do some work
>
// .
?>
With PHP7.4, in_array returns boolean true.
With PHP8.1, in_array returns boolean false.
It took me quite some time to find out what’s going on.
I found out that in_array will *not* find an associative array within a haystack of associative arrays in strict mode if the keys were not generated in the *same order*:
$needle = array(
‘fruit’ => ‘banana’ , ‘vegetable’ => ‘carrot’
);
$haystack = array(
array( ‘vegetable’ => ‘carrot’ , ‘fruit’ => ‘banana’ ),
array( ‘fruit’ => ‘apple’ , ‘vegetable’ => ‘celery’ )
);
echo in_array ( $needle , $haystack , true ) ? ‘true’ : ‘false’ ;
// Output is ‘false’
echo in_array ( $needle , $haystack ) ? ‘true’ : ‘false’ ;
// Output is ‘true’
?>
I had wrongly assumed the order of the items in an associative array were irrelevant, regardless of whether ‘strict’ is TRUE or FALSE: The order is irrelevant *only* if not in strict mode.
I’d like to point out that, if you’re using Enum data structures and want to compare whether an array of strings has a certain string Enum in it, you need to cast it to a string.
From what I’ve tested, the function works correctly:
if the array is filled with strings and you’re searching for a string;
if the array is filled with Enums and you’re searching for an Enum.
Here is a recursive in_array function:
$myNumbers = [
[ 1 , 2 , 3 , 4 , 5 ],
[ 6 , 7 , 8 , 9 , 10 ],
];
$array = [
‘numbers’ => $myNumbers
];
// Let’s try to find number 7 within $array
$hasNumber = in_array ( 7 , $array , true ); // bool(false)
$hasNumber = in_array_recursive ( 7 , $array , true ); // bool(true)
function in_array_recursive ( mixed $needle , array $haystack , bool $strict ): bool
foreach ( $haystack as $element ) if ( $element === $needle ) return true ;
>
$isFound = false ;
if ( is_array ( $element )) $isFound = in_array_recursive ( $needle , $element , $strict );
>
if ( $isFound === true ) return true ;
>
>
If you’re creating an array yourself and then using in_array to search it, consider setting the keys of the array and using isset instead since it’s much faster.
$slow = array( ‘apple’ , ‘banana’ , ‘orange’ );
if ( in_array ( ‘banana’ , $slow ))
print( ‘Found it!’ );
$fast = array( ‘apple’ => ‘apple’ , ‘banana’ => ‘banana’ , ‘orange’ => ‘orange’ );
if (isset( $fast [ ‘banana’ ]))
print( ‘Found it!’ );
array_search
Замечание:
Если needle является строкой, сравнение происходит с учетом регистра.
Если третий параметр strict установлен в TRUE , то функция array_search() будет искать идентичные элементы в haystack . Это означает, что также будут проверяться типы needle в haystack , а объекты должны быть одни и тем же экземпляром.
Возвращаемые значения
Возвращает ключ для needle , если он был найден в массиве, иначе FALSE .
Если needle присутствует в haystack более одного раза, будет возвращён первый найденный ключ. Для того, чтобы возвратить ключи для всех найденных значений, используйте функцию array_keys() с необязательным параметром search_value .
Эта функция может возвращать как boolean FALSE , так и не-boolean значение, которое приводится к FALSE . За более подробной информацией обратитесь к разделу Булев тип. Используйте оператор === для проверки значения, возвращаемого этой функцией.
Список изменений
Версия | Описание |
---|---|
5.3.0 | Вместе со всеми внутренними функциями PHP начиная с 5.3.0, array_search() возвращает NULL , если ей были переданы неверные параметры. |
4.2.0 | До PHP 4.2.0, array_search() при неудаче возвращал NULL вместо FALSE . |
Примеры
Пример #1 Пример использования array_search()
$array = array( 0 => ‘blue’ , 1 => ‘red’ , 2 => ‘green’ , 3 => ‘red’ );
?php
$key = array_search ( ‘green’ , $array ); // $key = 2;
$key = array_search ( ‘red’ , $array ); // $key = 1;
?>
Смотрите также
- array_keys() — Возвращает все или некоторое подмножество ключей массива
- array_values() — Выбирает все значения массива
- array_key_exists() — Проверяет, присутствует ли в массиве указанный ключ или индекс
- in_array() — Проверяет, присутствует ли в массиве значение