Catrina пыталась создать подобную тему, но там всё скатилось в трёп, - это "попытка 2". Гуру, присоединяйтесь. Начну с пары простейших примочек... 1) Аналог trim() для unicode - удаляет все пробельные символы в начале и в конце. Код (PHP): preg_replace('/^\s+|\s+$/u', '', $text) 2) Swap - меняет значения переменных местами. Код (PHP): function Swap(&$p1, &$p2) { $tmp = $p1; $p1 = $p2; $p2 = $tmp; } 3) LastKey - возвращает ключ последнего элемента массива. Код (PHP): function LastKey(array $a) { end($a); return key($a); }
Тема хорошая. Замечу только, что обычный Трим вполне мультибайтно-безопасный. http://stackoverflow.com/a/10067670/272885 Добавлено спустя 32 минуты 48 секунд: Полезные кейсы оператора "+" с массивами: Значения по умолчанию: Код (PHP): $defaults = ['host' => 'localhost', 'user' => 'root', 'password' => '']; var_dump($array + $defaults); Значения по умолчанию и при этом оставить только те ключи массива, которые упоминаются в дефолтовом массиве: Код (PHP): $defaults = ['host' => 'localhost', 'user' => 'root', 'password' => '']; var_dump(array_intersect_key($array, $defaults) + $defaults); Сравнение нескольких "полей" сразу: Код (PHP): $condition = ['name' => 'John', 'city' => 'New York']; If ($condition + $array == $array) echo 'Ok';
Да, очень удобная. Я часто пользуюсь подобной конструкцией для назначения default-значений. Что-то типа: Код (PHP): function F($param, $options=[]) { $options += ['option1'=>value1, 'option2'=>value2, ...] // т.е. option1 всегда будет, или назначен или по умолчанию. ... }
если нужно выкинуть из массива все пустые строки с нулями Код (PHP): print_r( array_filter( ['',0,1,'2','a'] ) ); // 1,2,a
Дополню runcore. 4) array_filter а) Удалить из массива элементы только со значением NULL. Код (PHP): array_filter($array, function($v) { return $v !== null; } ) б) Удалить из массива элементы только со значениями NULL и пустая строка (в т.ч. состоящая из одних пробелов). Код (PHP): array_filter($array, function($v) { return $v !== null and trim($v) !== ''; } )
5) Заменить слово, содержащие кусок текста. Код (PHP): preg_replace('/(\b\w*текст\w*\b)/ui', '#', $source) Пример из другого топика другого форума: Код (PHP): $s = 'Вот приехал сосед из соседней деревни пососедству'; var_dump(htmlentities(preg_replace('/(\b\w*сосед\w*\b)/ui', '<b>$1</b>', $s))); // "Вот приехал <b>сосед</b> из <b>соседней</b> деревни <b>пососедству</b>"
6) Сравнить два JSON,ARRAY значения по ключам. Код (PHP): /** * Сравнивает два JSON, ARRAY значения по ключам. * @param array|string $j1 ARRAY или JSON данные. * @param array|string $j2 ARRAY или JSON данные. * @return bool TRUE - равны, FALSE - не равны. */ function EqualRecursive($j1, $j2) { if(is_string($j1)) { $j1 = json_decode($j1, true); } if(is_string($j2)) { $j2 = json_decode($j2, true); } $equal = (count($j1) == count($j2) and !array_diff_key($j1, $j2)); if($equal) { foreach($j1 as $k=>$j) { if(is_array($j)) { $equal = KeysEqualRecursive($j, $j2[$k]); if(!$equal) break; } } } return $equal; } Тест: Код (PHP): var_dump( EqualRecursive('{"index": 0, "tags": ["abc"]}', '{"index": 1, "tags": ["xyz"]}')); // equal var_dump( EqualRecursive('{"tags": ["abc","def"], "index": 0}', '{"index": 1, "tags": ["xyz"]}')); // not equal var_dump( EqualRecursive('{"tags": ["abc"], "index": 0, "хрень": 0}', '{"index": 1, "tags": ["xyz"]}')); // not equal var_dump( EqualRecursive(["tags"=> ["abc"], "index"=> 0], ["index"=> 1, "tags"=> ["xyz"]])); // equal var_dump( EqualRecursive(["tags"=> ["abc"], "index"=> 0, "хрень"=> 0], ["index"=> 1, "tags"=> ["xyz"]])); // not equal
7) Получить все числа разделённые пробелами из текста: Код (PHP): preg_match_all('/(\d+\s*)+(?<!\D)/', $text, $out); Тест: Код (PHP): $text = 'Сумма 4 748 730 была получена из суммы 67 839 умноженной на коэффициент K = 70'; preg_match_all('/(\d+\s*)+(?<!\D)/', $text, $out); var_dump($out[0]);
8) Аналог trim() для unicode - удаляет все пробельные символы в начале и в конце: Код (PHP): preg_replace('/^\s+|\s+$/u', '', $text)
9) Заменить N-ое вхождение части строки. Например, заменить третью двойку на "0" и четвёртый символ "b" на "B": Код (PHP): $s = 'бе бе 123 123 123 123 abc abc abc abc'; var_dump(preg_replace(['/(.*2.*2.*)(2)/U', '/(.*b.*b.*b.*)(b)/U'], ['${1}0', '${1}B'], $s)); // результат: string(41) "бе бе 123 123 103 123 abc abc abc aBc"
10) Поменять соседние символы строки местами. Например, “Hello World!” -> “eHll ooWlr!d”: PHP: $s = 'Hello World!'; var_dump(preg_replace('/(.)(.)/u', '$2$1' $s));
11) Заключить текст между разделителями в HTML-теги Код (PHP): $text= ' Часть 1 ---------------------------------------------------------------------- Некий текст до следующего разделителя ---------------------------------------------------------------------- Часть 2 ---------------------------------------------------------------------- Текст ---------------------------------------------------------------------- Прочая хрень... '; //Например, разделитель это 65 или более тире подряд с горизонтальными пробелами до: $resultat1 = preg_replace('/((?:\h*\-{65,})(?:.*?)(?:\-{65,}))/us', "<pre>\n$1\n</pre>", $text); var_dump(htmlspecialchars($resultat1)); // п.с. (?:) использовано для наглядности // Более сложный вариант: разделить текст на три части, - первый разделитель, текст между // разделителями, второй разделитель. Перед первым разделителем открыть тег PRE, после // второго закрыть, текст заключить в тег B. Разделитель это 65 или более тире подряд с // горизонтальными пробелами до и после. $resultat2 = preg_replace('/(\h*\-{65,}\h*)(.*?)(\h*\-{65,}\h*)/us', "<pre>\n$1\n<b>$2</b>\n$3\n</pre>", $text); var_dump(htmlspecialchars($resultat2)); Результат 1: Код (Text): string(479) " Часть 1 <pre> ---------------------------------------------------------------------- Некий текст до следующего разделителя ---------------------------------------------------------------------- </pre> Часть 2 <pre> ---------------------------------------------------------------------- Текст ---------------------------------------------------------------------- </pre> Прочая хрень... " Результат 2: Код (Text): string(521) " Часть 1 <pre> ---------------------------------------------------------------------- <b> Некий текст до следующего разделителя </b> ---------------------------------------------------------------------- </pre> Часть 2 <pre> ---------------------------------------------------------------------- <b> Текст </b> ---------------------------------------------------------------------- </pre> Прочая хрень... "
Как увеличить время (таймстамп) на один день внезапно! Казалось бы, прибавляй 24 * 60 * 60 и радуйся. Это так, если не знать про смену времени зима/лето, которая происходит в половине стран или провинций стран. При наступлении даты Д мы получим время на час меньше или больше, чем хотелось (в текстовом представлении конечно). Безопасный и элегантный способ: 1. установить текущий часовой пояс в начале работы, типа Код (Text): date_default_timezone_set('Australia/Melbourne'); 2. прибавлять или отнимать через функцию strtotime. здесь строкой является только "команда", второй аргумент это таймстамп и на выходе тоже таймстамп. Код (Text): $next = strtotime('+1 day', $current); в зависимости от контекста здесь происходит увеличение на 23, 24 или 25 часов. date('Y-m-d H:i:s', $next) будет всегда тот, что мы ожидали увидеть.
а есть пример применения этого дела? много раз видел подобную задачу, но на практике как-то не сталкивался.
12) Удалить строки из массива, все слова которых входят в другие строки. см. тему Сопоставлении массивов...
13) Получить записи с чётными и нечётными ключами, для значений больше нуля. Вариант без сохранения ключей: PHP: $data = [2,1,2,3,5,7,9,11,4,0,0]; $odd = array_column(array_chunk(array_filter($data), 2), 1); $even = array_column(array_chunk(array_filter($data), 2), 0); Вариант с сохранением ключей: PHP: $data = [2,1,2,3,5,7,9,11,4,0,0]; $odd = array_filter($data, function($v, $k) { return ($k % 2 and $v > 0); }, ARRAY_FILTER_USE_BOTH); $even = array_filter($data, function($v, $k) { return (!($k % 2) and $v > 0); }, ARRAY_FILTER_USE_BOTH); Вариант с сохранением ключей без использования функций: PHP: $data = [2,1,2,3,5,7,9,11,4,0,0]; $odd = []; $even = []; foreach($data as $k=>$v) { if(!($k % 2) and $v > 0) { $even[$k] = $v; } elseif($k % 2 and $v > 0) { $odd[$k] = $v; } }
14) Понижение n-мерности массивов. Спойлер: Описание array_undimention(array $array[,int $final_deep = 1]) Приводит N-мерный массив с однородной структурой к количеству измерений, указанному в $final_deep. Передаваемые параметры: array $array Массив, который требуется обработать. int $final_deep = 1 Необязательный параметр. Количество измерений, к которым нужно привести $array. По умолчанию равен 1. Возвращаемые значения: ($final_deep)-мерная версия массива $array, либо false в случае, если $array не является массивом, и/или $final_deep<1. Замечания: При снижении мерности массивов, ключи измерения N отбрасываются, а их значения смерживаются в одно единое измерение. Таким образом, к примеру, при сведении какого-либо массива к 1-мерному, он будет представлять собой список значений, которые имели максимальный индекс вложенности. Передаваемый массив должен иметь однородную структуру. То есть, любая ячейка должна иметь ту же иерархию элементов, что и начальная. Количество вложенных элементов у разных ячеек значения не играет. Важно лишь единство структуры. Структура массива определяется по первой ячейке. PHP: function array_undimention($array, $final_deep = 1) { if ((is_array($array)) && ($final_deep >= 1)) { $temp = current($array); $real_deep = 1; while (is_array($temp)) { $temp = current($temp); $real_deep++; } if ($real_deep > $final_deep) { $temp = []; foreach ($array as $cell) { foreach ($cell as $sub_cell) { $temp[] = $sub_cell; } } $temp = array_undimention($temp, $final_deep); } else { $temp = $array; } return $temp; } return false; }
Решений есть масса без применения промежуточных переменных К примеру: PHP: $a = 5; $b = 10; $a = [$b, $b = $a][0]; var_dump($a, $b); //10, 5 @Fell-x27 Напиши, пример, на входе такой массив, нужно получить такой.
Допустим, к нам пришел вот такой четырехмерный массив: PHP: $arr = [ "data1" => [ "cat1" => [ "val1" => [1, 2], "val2" => [3, 4], "val3" => [5, 6], "val4" => [7, 8] ], "cat2" => [ "val1" => [10, 20], "val2" => [40, 40], "val3" => [50, 60], "val4" => [70, 80] ] ], "data2" => [ "cat1" => [ "val1" => [100, 200], "val2" => [300, 400], "val3" => [500, 600], "val4" => [700, 800] ], "cat2" => [ "val1" => [1000, 2000], "val2" => [3000, 4000], "val3" => [5000, 6000], "val4" => [7000, 8000] ] ] ]; А нас интересует только содержимое последних массивов с числами, но так, чтобы они оставались массивами. То есть, нужно отсечь первые 2 измерения, чтобы остались только последние два. Код (Text): $new_arr = array_undimention($arr,2); Результатом будет такой массив: PHP: $new_arr = [ 0 => [1, 2], 1 => [3, 4], 2 => [5, 6], 3 => [7, 8], 4 => [10, 20], 5 => [40, 40], 6 => [50, 60], 7 => [70, 80], 8 => [100, 200], 9 => [300, 400], 10 => [500, 600], 11 => [700, 800], 12 => [1000, 2000], 13 => [3000, 4000], 14 => [5000, 6000], 15 => [7000, 8000] ]; Если же для $arr указать вторым параметром единицу, то получим просто одномерный массив PHP: $flat_arr = [1,2,3,4,5,6,7,8,10,20,30,40,50,60,70,80,100,200,300,400,500,600,700,800,900,1000,2000,3000,4000,5000,6000,7000,8000];
$flat_arr можно получить так PHP: function flatArray($arr) { $buildValue = function ($value) use (&$result) { $result[] = $value; }; array_walk_recursive($arr, $buildValue); return $result; } Честно, не встречал подобных задач где данный подход нужен
Все бывает однажды. Но только именно flat. Контроля над конечной вложенностью нет. Так-то, естественно не проблема просто "собрать листья с дерева". Но и не исключаю, что мое решение можно отрефакторить. Оно довольно старое
15) Рассчитать сумму элементов многомерного массива с группировкой по ключам Проще всего использовать array_walk_recursive() с параметром use(). Пример: PHP: // Исходные данные $in = [ 'a' => 1, 'b' => 2, 'c' => 5, 'a1' => [ 'a' => 1, 'b' => 2, 'c' => 5 ], 'a2' => [ 'a' => 1, 'b' => 2, 'c' => 5, 'd' => 10, 'b1' => [ 'a' => 1, 'b' => 2, 'c' => 5, 'f' => 100 ], 'b2' => [ 'a' => 1, 'b' => 2, 'c' => 5, 'c1' => [ 'a' => 1, 'b' => 2, 'c' => 5, 'f' => 100 ] ] ] ]; // Непосредственно алгоритм $sum = []; array_walk_recursive($in, function($v, $k) use(&$sum) { @$sum[$k] += $v; }); // Отображение результата var_dump($sum); /* array(5) { ["a"]=> int(6) ["b"]=> int(12) ["c"]=> int(30) ["d"]=> int(10) ["f"]=> int(200) } */