Умное использование функций массива PHP

задняя часть PHP открытый источник продукт

0x00 Предисловие

Массив в PHP — очень мощный тип данных, в то же время PHP имеет ряд встроенных функций, связанных с массивами, которые могут легко реализовать функции повседневной разработки. Но я обнаружил, что многие небольшие партнеры, похоже, игнорируют роль встроенных функций (например, я написал код для операций с массивами и обнаружил, что PHP поставляется с /(ㄒoㄒ)/~~), эффективно используя PHP встроенные функции могут значительно повысить эффективность разработки и эффективность работы (встроенные функции написаны на C более эффективно, чем написанные на PHP), поэтому в этой статье приведены некоторые методы реализации использования встроенных функций PHP в распространенных сценариях. . Кроме того, если вы хотите узнать больше о функциях работы с массивами в PHP, лучше всего обратиться к руководству по PHP!Я думаю, что официальные функции Point Array Manual

0x01 Взять указанное имя ключа

Для некоторых ассоциативных массивов иногда мы хотим взять только часть указанного имени ключа, например, массив['id' => 1, 'name' => 'zane', 'password' => '123456']В настоящее время, как реализовать, если вы хотите взять только часть, содержащую идентификатор и имя? Вставьте код прямо ниже.

<?php
$raw = ['id' => 1, 'name' => 'zane', 'password' => '123456'];
// 自己用 PHP 实现
function onlyKeys($raw, $keys) {
    $new = [];
    foreach ($raw as $key => $val) {
        if (in_array($key, $keys)) {
            $new[$key] = $val;
        }
    }
    
    return $new;
}
// 用 PHP 内置函数实现
function newOnlyKeys($array, $keys) {
    return array_intersect_key($array, array_flip($keys));
}
var_dump(onlyKeys($raw, ['id', 'name']));
// 结果 ['id' => 1, 'name' => 'zane']
var_dump(newOnlyKeys($raw, ['id', 'name']));
// 结果 ['id' => 1, 'name' => 'zane']

Видно, что в нем много простоты! ноarray_intersect_keyиarray_flipкакого черта? Вот краткое введение в роль этих двух функций, первыйarray_flipФункция, функция этой функции - это «ключ и значение массива», то есть имя ключа становится значением, значение превращается в ключевое имя. Мы прошли$keysПараметры передаются через эту функцию из[0 => 'id', 1 => 'name']превратился в['id' => 0, 'name' => 1]. Цель этого состоит в том, чтобыarray_intersect_keyфункциональное обслуживание,array_intersect_keyФункция функции состоит в том, чтобы «использовать сравнение имени ключа для вычисления пересечения массивов», то есть возвращать значение того же имени ключа в первом массиве параметров, что и в других массивах параметров. Таким образом реализуется функция взятия указанного имени ключа ~(≧▽≦)/~! Конечно, чтобы узнать больше о функциях этих двух функций, вам все равно нужно проверить официальное руководство по PHP:array_flip array_intersect_key

0x02 удалить указанное имя ключа

С предыдущим примером в качестве предзнаменования, этот будет кратко объяснен.Правда аналогична.

<?php
$raw = ['id' => 1, 'name' => 'zane', 'password' => '123456'];
// 用 PHP 内置函数实现
function removeKeys($array, $keys) {
    return array_diff_key($array, array_flip($keys));
}
// 移除 id 键
var_dump(removeKeys($raw, ['id', 'password']));
// 结果 ['name' => 'zane']

По сравнению с предыдущим примером, этот пример изменяет толькоarray_intersect_keyфункция изменена наarray_diff_keyхм... я думаю, что каждый может догадаться, что такое функция этой функции "использовать имя ключа для сравнения и вычисления разницы массива", которая точно такая же, какarray_intersect_keyФункция как раз обратная. Официальное руководство:array_diff_key

0x03 Дедупликация массива

Я считаю, что у нас есть этот спрос, конечно, PHP также встроенarray_uniqueФункция доступна для всех, например:

<?php
$input = ['you are' => 666, 'i am' => 233, 'he is' => 233, 'she is' => 666];
$result = array_unique($input);
var_dump($result);
// 结果 ['you are' => 666, 'i am' => 233]

Эй, эта функция решит большинство проблем, но иногда вам может показаться, что она работает недостаточно быстро по следующим причинам:

array_unique()Значения сначала сортируются как строки, затем для каждого значения сохраняется только первое встретившееся имя ключа, а все последующие имена ключей игнорируются.

Поскольку эта функция сначала сортирует массив, в некоторых сценариях скорость может не соответствовать ожидаемым требованиям.

Теперь мы можем пожертвовать нашей черной технологиейarray_flipФункции, как мы все знаем, ключевые имена массивов в PHP уникальны, поэтому дубликаты значений игнорируются после того, как имя ключа и значения поменяются. Представьте, что мы называем дважды подрядarray_flipФункция не эквивалентна для достиженияarray_uniqueКак насчет функции функции? Пример кода выглядит следующим образом:

<?php
$input = ['you are' => 666, 'i am' => 233, 'he is' => 233, 'she is' => 666];
$result = array_flip(array_flip($input));
var_dump($result);
// 结果 ['she is' => 666, 'he is' => 233]

Ага? ! результат иarray_uniqueэто отличается! Почему, мы можем получить ответ из официального руководства по PHP:

Если одно и то же значение появляется несколько раз, в качестве его значения будет использоваться последнее имя ключа, а остальные ключи будут отброшены.

В целом этоarray_uniqueсохранить первое вхождение имени ключа,array_flipЗарезервированные ключи Последнее появление.

Уведомление:использоватьarray_flipПри дедупликации в виде массива значение массива должно иметь возможность использоваться в качестве имени ключа (то есть иметь строковый или целочисленный тип), иначе значение будет проигнорировано.

Кроме того, если нам не нужно резервировать имя ключа, мы можем использовать его напрямую, как этоarray_values(array_flip($input)).

0x04 индекс сброса

Когда мы хотим сбросить массив, индексы которого не являются последовательными, например массив:[0 => 233, 99 => 666], для такого массива нам просто нужно вызватьarray_valuesфункция может быть реализована. Например:

<?php
$input = [0 => 233, 99 => 666];
var_dump(array_values($input));
// 结果 [0 => 233, 1 => 66]

должен быть в курсеarray_valuesФункция не только сбрасывает числовой индекс, но также удаляет и сбрасывает строковый ключ. Итак, как мне сбросить числовой индекс, сохранив имя строкового ключа? ответarray_sliceфункции, пример кода выглядит следующим образом:

<?php
$input = ['hello' => 'world', 0 => 233, 99 => 666];
var_dump(array_slice($input, 0));
// 结果 ['hello' => 'world', 0 => 233, 1 => 66]

array_sliceФункция функции состоит в том, чтобы удалить раздел массива, но она изменит порядок и сбросит числовой индекс массива по умолчанию, поэтому вы можете использовать его для сброса числового индекса в массиве.

0x05 очистить нулевое значение

Эй, иногда мы хотим очистить пустые значения в массиве, например:null,false,0,0.0,[]空数组,''空字符串,'0'字符串0, тогдаarray_filter函数便能帮上大忙。 код показывает, как показано ниже:

<?php
$input = ['foo', false, -1, null, '', []];
var_dump(array_filter($input));
// 结果 [0 => 'foo', 2 => -1]

Почему появляется этот результат?array_filterФункция на самом деле «использует функцию обратного вызова для фильтрации элементов в массиве». Ее второй параметр на самом деле является функцией обратного вызова, которая выполняется для каждого члена массива. Если возвращаемое значение функции обратного вызова равноtrueсохранить этого члена дляfalseигнорируется. Еще одной особенностью этой функции является:

если не предусмотреноcallbackфункция, удалитarrayВсе эквиваленты вFALSEзапись.

Эквивалентное значение false означает, что после преобразования в тип bool значение становится ложным.Подробности см. в документации:Преобразовать в логический тип.

Уведомление: если не заполненоcallbackфункция,0,0.0,'0'字符串0Эти потенциально значимые значения удаляются. Так что если правила клиринга отличаются, нужно написать своиcallbackфункция.

0x06 Подтвердить, что все члены массива верны

Иногда мы хотим убедиться, что значения в массиве всеtrue,Например:['read' => true, 'write' => true, 'execute' => true], то нам нужно использовать цикл для определения? НЕТ, НЕТ, НЕТ... просто используйтеarray_productфункция может быть реализована. код показывает, как показано ниже:

<?php
$power = ['read' => true, 'write' => true, 'execute' => true];
var_dump((bool)array_product($power));
// 结果 true
$power = ['read' => true, 'write' => true, 'execute' => false];
var_dump((bool)array_product($power));
// 结果 false

Почему эта функция может быть достигнута?array_productПервоначальная функция функции состоит в том, чтобы «вычислить произведение всех значений в массиве».При умножении всех членов в массиве значение члена будет преобразовано в числовой тип. Когда переданный параметр является массивом элементов bool, это хорошо известно.trueбудет преобразовано в 1,falseбудет преобразовано в 0. тогда, пока есть один в массивеfalseРезультат кумулятивного умножения естественно станет 0, а затем мы преобразуем результат вboolтип неfalseНу давай же!

Уведомление:использоватьarray_productФункция преобразует элемент массива в числовой тип во время процесса вычисления, поэтому убедитесь, что вы понимаете значение члена массива, преобразованного в числовой тип, иначе это приведет к неожиданным результатам. Например:

<?php
$power = ['read' => true, 'write' => true, 'execute' => 'true'];
var_dump((bool)array_product($power));
// 结果 false

Вышеприведенный пример потому, что'true'при расчете сбрасывается в 0. Чтобы узнать больше, пожалуйстакликните сюда.

0x07 Получить массив до/после указанного имени ключа

Что, если нам нужна только часть ассоциативного массива перед указанным значением ключа? Еще одна петля? Конечно нет, мы можем пройтиarray_keys,array_searchиarray_sliceМожно в комплексе! Вставьте код ниже:

<?php
$data = ['first' => 1, 'second' => 2, 'third' => 3];
function beforeKey($array, $key) {
    $keys = array_keys($array);
  	// $keys = [0 => 'first', 1 => 'second', 2 => 'third']
    $len = array_search($key, $keys);
    return array_slice($array, 0, $len);
}
var_dump(beforeKey($data, 'first'));
// 结果 []
var_dump(beforeKey($data, 'second'));
// 结果 ['first' => 1]
var_dump(beforeKey($data, 'third'));
// 结果 ['first' => 1, 'second' => 2]

Анализ идей, для достижения такой функции большинство учащихся должны уметь думать об этом.array_sliceфункция, но эта функция берет часть массива по смещению (под которым можно понимать порядок имен ключей в массиве, начиная с 0) вместо имени ключа, а имя ключа ассоциативного массива равно строка или не числа по порядку, проблема, которая должна быть решена в настоящее время, заключается в том, «как получить смещение, соответствующее имени ключа?», чтоarray_keysЭта функция нам очень помогла.Ее функция состоит в том, чтобы "возвратить некоторые или все имена ключей в массиве" и вернуть все имена ключей по умолчанию.Кроме того, возвращаемый массив имен ключей имеет числовую индексацию, то есть , возвращаемый массив имени ключа: Индекс — это смещение! Исходный массив в примере становится:[0 => 'first', 1 => 'second', 2 => 'third']. Затем мы проходимarray_searchВы можете получить смещение указанного имени ключа, потому что функция этой функции — «искать заданное значение в массиве и в случае успеха возвращать первое соответствующее имя ключа». Со смещением мы звоним напрямуюarray_sliceфункция может достичь своей цели.

Приведенный выше пример понятен, тогда легко получить массив после указанного имени ключа, немного видоизмененногоarray_sliceВот и все. Вставьте код напрямую:

<?php
$data = ['first' => 1, 'second' => 2, 'third' => 3];
function afterKey($array, $key) {
    $keys = array_keys($array);
    $offset = array_search($key, $keys);
    return array_slice($array, $offset + 1);
}
var_dump(afterKey($data, 'first'));
// 结果 ['second' => 2, 'third' => 3]
var_dump(afterKey($data, 'second'));
// 结果 ['third' => 3]
var_dump(afterKey($data, 'third'));
// 结果 []

Итак, как получить массив до или после указанного значения? эй помниarray_searchРоль его, по сути, нам нужно только назвать вот этимbeforeKey($data, array_search($value, $data))Разве это не осознается!

0x08 Самое повторяющееся значение в массиве

Стучите по доске и нарисуйте ключевые моменты! Говорят, что это вопрос для интервью. Допустим есть такой массив[6, 11, 11, 2, 4, 4, 11, 6, 7, 4, 2, 11, 8], как получить самое повторяющееся значение в массиве? Дело в томarray_count_valuesфункция. Пример кода выглядит следующим образом:

<?php
$data = [6, 11, 11, 2, 4, 4, 11, 6, 7, 4, 2, 11, 8];
$cv = array_count_values($data);
// $cv = [6 => 2, 11 => 4, 2 => 2, 4 => 3, 7 => 1, 8 => 1]
arsort($cv);
$max = key($cv);
var_dump($max);
// 结果 11

array_count_valuesФункция функции состоит в том, чтобы «подсчитать все значения в массиве», то есть значение в исходном массиве используется как имя ключа возвращаемого массива, а количество вхождений значения используется как значение возвращаемого массива. чтобы мы могли пройтиarsortФункция сортирует вхождения в порядке убывания и поддерживает индексную ассоциацию. последнее использованиеkeyПолучить имя ключа текущего блока (по умолчанию текущий блок является первым элементом массива), а имя ключа в это время — это значение с наибольшим количеством повторений значения исходного массива.

0x09 Время рекламы

Хотя PHP предоставляет множество функций, связанных с массивами, он не очень удобен в использовании, и все они вызываются функциями без объектно-ориентированных реализаций, поэтому недавно я пишу проект инструмента с открытым исходным кодом.zane/utils, который инкапсулирует некоторые часто используемые методы и поддерживает цепные вызовы. Класс Ary реализует «получение наиболее повторяющегося значения в массиве» только с одной строкой, как показано ниже:

$data = [6, 11, 11, 2, 4, 4, 11, 6, 7, 4, 2, 11, 8];
$max = Ary::new($data)->countValues()->maxKey();
var_dump($max);
// 结果 11

Вы можете присылать мне вопросы и PR, и если вам нравится этот проект, вы хотели бы нажать на звезду :-D

адрес проекта:GitHub.com/Мы, Демоническая Мать/, вы упомянули…

0x0A Эпилог

На самом деле есть много практических функций, которые не были представлены, но я расскажу о них здесь из-за объема статьи. Многие из примеров в этой статье не являются оригинальными для меня, большинство из нихОфициальное руководство по PHP(В комментариях под каждой функцией есть много великих богов, которые предложили несколько мощных способов использования, а некоторые примеры взяты из комментариев). Нижеследующее просто собирает человеческую мудрость и обобщает ее. Кроме того, если в статье есть ошибка, надеюсь, все смогут указать на нее, а если возникнут вопросы, то можно обсудить друг с другом :-D.

мой блог оригинал