Python zip in php

Есть ли функция php, такая как python zip?

У Python есть хорошая функция zip() . Есть ли эквивалент PHP?

ОТВЕТЫ

Ответ 1

Пока все массивы имеют одинаковую длину, вы можете использовать array_map с null в качестве первого аргумента.

Если некоторые из массивов короче, они будут дополнены нулями до длины самого длинного, в отличие от python, где возвращаемый результат — длина самого короткого массива.

Ответ 2

Попробуйте эту функцию для создания массива массивов, подобных Pythons zip :

function zip() < $args = func_get_args(); $zipped = array(); $n = count($args); for ($i=0; $iwhile ($n) < $tmp = array(); for ($i=0; $i$tmp[] = current($args[$i]); next($args[$i]); > $zipped[] = $tmp; > return $zipped; > 

Вы можете передать эту функцию столько, сколько хотите, сколько угодно элементов.

Ответ 3

В противном случае ничего похожего на кодирование:

function array_zip($a1, $a2) < for($i = 0, $i < min(length($a1), length($a2)); $i++) < $out[$i] = [$a1[$i], $a2[$i]]; >return $out; > 

Ответ 4

Этот работает точно так же, как функция Python zip() , и также совместим с PHP < 5.3:

function zip() < $params = func_get_args(); if (count($params) === 1)< // this case could be probably cleaner // single iterable passed $result = array(); foreach ($params[0] as $item)< $result[] = array($item); >; return $result; >; $result = call_user_func_array('array_map',array_merge(array(null),$params)); $length = min(array_map('count', $params)); return array_slice($result, 0, $length); >; 

Он объединяет массивы так, как это делает Python zip() , и не возвращает элементы, найденные после достижения конца самого короткого массива.

zip(array(1,2,3,4,5),array('a','b'),array('x','y','z')); 

Отметьте эту демонстрацию для доказательства вышеуказанного.

EDIT: добавлена ​​поддержка для приема одного аргумента ( array_map ведет себя по-другому в этом случае, спасибо Josiah).

Ответ 5

Решение

Решение, соответствующее zip() очень близко и используя встроенные функции PHP в одно и то же время:

array_slice( array_map(null, $a, $b, $c), // zips values 0, // begins selection before first element min(array_map('count', array($a, $b, $c))) // ends after shortest ends ); 

Почему не простой вызов array_map(null, $a, $b, $c) ?

Как уже упоминалось в моем комментарии, я склоняюсь к решению nabnabit ( array_map(null, $a, $b, . ) ), но слегка измененным образом (показано выше).

является аналогом для Python’s:

itertools.izip_longest(a, b, c, fillvalue=None) 

(оберните его в list() , если вам нужен список вместо итератора). Из-за этого он точно не соответствует требованию для имитации поведения zip() (если все массивы не имеют одинаковой длины).

Ответ 6

Я написал функции zip() для PHP-реализация перечисления.
Код был изменен, чтобы использовать стиль zip() в стиле Python, а также стиль Ruby. Разница объясняется в комментариях:

/* * This is a Python/Ruby style zip() * * zip(array $a1, array $a2, . array $an, [bool $python=true]) * * The last argument is an optional bool that determines the how the function * handles when the array arguments are different in length * * By default, it does it the Python way, that is, the returned array will * be truncated to the length of the shortest argument * * If set to FALSE, it does it the Ruby way, and NULL values are used to * fill the undefined entries * */ function zip() < $args = func_get_args(); $ruby = array_pop($args); if (is_array($ruby)) $args[] = $ruby; $counts = array_map('count', $args); $count = ($ruby) ? min($counts) : max($counts); $zipped = array(); for ($i = 0; $i < $count; $i++) < for ($j = 0; $j < count($args); $j++) < $val = (isset($args[$j][$i])) ? $args[$j][$i] : null; $zipped[$i][$j] = $val; >> return $zipped; > 
$pythonzip = zip(array(1,2,3), array(4,5), array(6,7,8)); $rubyzip = zip(array(1,2,3), array(4,5), array(6,7,8), false); echo '
'; print_r($pythonzip); print_r($rubyzip); echo '
'; 

Ответ 7

public static function array_zip() < $result = array(); $args = array_map('array_values',func_get_args()); $min = min(array_map('count',$args)); for($i=0; $i$arr) < $result[$i][$j] = $arr[$i]; >> return $result; > 

Ответ 8

// create $a = array("a", "c", "e", "g", "h", "i"); $b = array("b", "d", "f"); $zip_array = array(); // get length of the longest array $count = count(max($a, $b)); // zip arrays for($n=0;$n <$count;$n++)< if (array_key_exists($n,$a))< $zip_array[] = $a[$n]; >if (array_key_exists($n,$b)) < $zip_array[] = $b[$n]; >> // test result echo '
'; print_r($zip_array); echo '
'; 

Ответ 9

вы можете увидеть способ array_map :

$arr1 = ['get', 'method']; $arr2 = ['post']; $ret = array_map(null, $arr1, $arr2); 

Ответ 10

Вы можете найти zip, а также другие функции Python в Нестандартная библиотека PHP. Включая операторский модуль и defaultarray.

use function nspl\a\zip; $pairs = zip([1, 2, 3], ['a', 'b', 'c']); 

Ответ 11

Чтобы преодолеть проблемы с передачей одного массива в map_array , вы можете передать эту функцию. к сожалению, вы не можете передать "array" , поскольку это не настоящая функция, а встроенная вещь.

Ответ 12

Посвященный тем, кто считает, что это должно быть связано с array_combine:

Источник

Is there a php function like python's zip?

Python has a nice zip() function. Is there a PHP equivalent?

Php Solutions

Solution 1 - Php

As long as all the arrays are the same length, you can use array_map with null as the first argument.

If some of the arrays are shorter, they will be padded with nulls to the length of the longest, unlike python where the returned result is the length of the shortest array.

Solution 2 - Php

Otherwise nothing like coding it yourself:

function array_zip($a1, $a2) < for($i = 0; $i < min(length($a1), length($a2)); $i++) < $out[$i] = [$a1[$i], $a2[$i]]; >return $out; > 

Solution 3 - Php

Try this function to create an array of arrays similar to Python’s zip :

function zip( ) < $args = func_get_args(); $zipped = array(); $n = count($args); for ($i=0; $i$n; ++$i) < reset($args[$i]); > while ($n) < $tmp = array(); for ($i=0; $i$n; ++$i) < if (key($args[$i]) === null) < break 2; > $tmp[] = current($args[$i]); next($args[$i]); > $zipped[] = $tmp; > return $zipped; > 

You can pass this function as many array as you want with as many items as you want.

Solution 4 - Php

This works exactly as Python's zip() function, and is compatible also with PHP < 5.3:

function zip( ) < $params = func_get_args(); if (count($params) === 1)< // this case could be probably cleaner // single iterable passed $result = array(); foreach ($params[0] as $item)< $result[] = array($item); >; return $result; >; $result = call_user_func_array('array_map',array_merge(array(null),$params)); $length = min(array_map('count', $params)); return array_slice($result, 0, $length); >; 

It merges the arrays in the manner Python's zip() does and does not return elements found after reaching the end of the shortest array.

gives the following result:

zip(array(1,2,3,4,5),array('a','b'),array('x','y','z')); 

gives the following result:

Check this demonstration for a proof of the above.

EDIT: Added support for receiving single argument ( array_map behaves differently in that case; thanks Josiah).

Solution 5 - Php

Solution

The solution matching zip() very closely, and using builtin PHP functions at the same time, is:

array_slice( array_map(null, $a, $b, $c), // zips values 0, // begins selection before first element min(array_map('count', array($a, $b, $c))) // ends after shortest ends ); 

Why not simple array_map(null, $a, $b, $c) call?

As I already mentioned in my comment, I tend to favor nabnabit's solution ( array_map(null, $a, $b, . ) ), but in a slightly modified way (shown above).

is counterpart for Python's:

itertools.izip_longest(a, b, c, fillvalue=None) 

(wrap it in list() if you want list instead of iterator). Because of this, it does not exactly fit the requirement to mimic zip() 's behaviour (unless all the arrays have the same length).

Solution 6 - Php

You can find zip as well as other Python functions in Non-standard PHP library. Including operator module and defaultarray.

use function nspl\a\zip; $pairs = zip([1, 2, 3], ['a', 'b', 'c']); 

Solution 7 - Php

I wrote a zip() functions for my PHP implementation of enum.
The code has been modified to allow for a Python-style zip() as well as Ruby-style. The difference is explained in the comments:

/* * This is a Python/Ruby style zip() * * zip(array $a1, array $a2, . array $an, [bool $python=true]) * * The last argument is an optional bool that determines the how the function * handles when the array arguments are different in length * * By default, it does it the Python way, that is, the returned array will * be truncated to the length of the shortest argument * * If set to FALSE, it does it the Ruby way, and NULL values are used to * fill the undefined entries * */ function zip( ) < $args = func_get_args(); $ruby = array_pop($args); if (is_array($ruby)) $args[] = $ruby; $counts = array_map('count', $args); $count = ($ruby) ? min($counts) : max($counts); $zipped = array(); for ($i = 0; $i < $count; $i++) < for ($j = 0; $j < count($args); $j++) < $val = (isset($args[$j][$i])) ? $args[$j][$i] : null; $zipped[$i][$j] = $val; > > return $zipped; > 
$pythonzip = zip(array(1,2,3), array(4,5), array(6,7,8)); $rubyzip = zip(array(1,2,3), array(4,5), array(6,7,8), false); echo '
'; print_r($pythonzip); print_r($rubyzip); echo '
'; 

Solution 8 - Php

/** * Takes an arbitrary number of arrays and "zips" them together into a single * array, taking one value from each array and putting them into a sub-array, * before moving onto the next. * * If arrays are uneven lengths, will stop at the length of the shortest array. */ function array_zip(. $arrays) < $result = []; $args = array_map('array_values',$arrays); $min = min(array_map('count',$args)); for($i=0; $i$min; ++$i) < $result[$i] = []; foreach($args as $j=>$arr) < $result[$i][$j] = $arr[$i]; > > return $result; > 
Array ( [0] => Array ( [0] => a [1] => 1 [2] => x ) [1] => Array ( [0] => b [1] => 2 [2] => y ) ) 

Solution 9 - Php

// create $a = array("a", "c", "e", "g", "h", "i"); $b = array("b", "d", "f"); $zip_array = array(); // get length of the longest array $count = count(max($a, $b)); // zip arrays for($n=0;$n$count;$n++)< if (array_key_exists($n,$a))< $zip_array[] = $a[$n]; > if (array_key_exists($n,$b))< $zip_array[] = $b[$n]; > > // test result echo '
'; print_r($zip_array); echo '
'; 

Solution 10 - Php

function zip( ) < $zip = []; $arrays = func_get_args(); if ($arrays) < $count = min(array_map('count', $arrays)); for ($i = 0; $i < $count; $i++) < foreach ($arrays as $array) < $zip[$i][] = $array[$i]; > > > return $zip; > 

Solution 11 - Php

This works like in Python

function zip(. $arrays) < return array_filter( array_map(null, . (count($arrays) > 1 ? $arrays : array_merge($arrays, [[]]))), fn($z) => count($z) === count(array_filter($z)) || count($arrays) === 1 ); > 

Solution 12 - Php

To overcome the issues with passing a single array to map_array , you can pass this function. unfortunately you can't pass "array" as it's not a real function but a builtin thingy.

function make_array() < return func_get_args(); > 

Solution 13 - Php

Dedicated to those that feel like it should be related to array_combine:

function array_zip($a, $b) < $b = array_combine( $a, $b ); $a = array_combine( $a, $a ); return array_values(array_merge_recursive($a,$b)); > 

Solution 14 - Php

you can see array_map method:

$arr1 = ['get', 'method']; $arr2 = ['post']; $ret = array_map(null, $arr1, $arr2); 

Источник

Есть ли PHP-функция, такая как Python Zip?

«Название говорит само за себя». Не совсем: что, если я действительно хорошо знаю PHP, но не знаю Python? По крайней мере, вы могли бы объяснить цель и использование "почтового индекса" Python .

12 ответов

Пока все массивы имеют одинаковую длину, вы можете использовать array_map с null в качестве первого аргумента.

Если некоторые из массивов короче, они будут дополнены нулями до длины самого длинного, в отличие от python, где возвращаемый результат - длина самого короткого массива.

Вы действительно пробовали это? array_map не ведет себя как zip Python. array_map(null, array(1,2), array(3)) возвращает array(array(1,3), array(2,null)) а zip([1,2], [3]) просто возвращает [(1,2)] .

@Gumbo Хотя это и есть способ Ruby, а не Python, я бы сказал, что он достаточно близок для большинства применений. Передача zip-массивов разной длины - это обычно не то, что вы делаете намеренно. Я добавил объяснение этого в ответ.

+1 На самом деле это больше похоже на itertools.izip_longest (. fillvalue = None), но это очень близко и все же лучшее решение. Если вы хотите получить точный результат, как в zip () Python, вы можете использовать array_slice (array_map (null, $ a, $ b), 0, min (count ($ a), count ($ b))) и получить точно что вы хотели, вероятно, наиболее эффективным способом.

Еще одна особенность этого метода в том, что он действует довольно странно, если вы используете его для одного массива, а не для нескольких. Если вы запустите array_map(null,array(1,2,3)) вы не получите, как и следовало ожидать, array(array(1),array(2),array(3)) , но вместо этого просто получите массив исходных значений, array(1,2,3) . Это, вероятно, не повлияет на большинство людей, но если вы пытаетесь сжать произвольное количество массивов (например, если число массивов определяется запросом к базе данных), это может стать довольно сложной задачей для отслеживать. Хорошее решение, если использовать только правильно, хотя.

Источник

Читайте также:  Zipping files in python
Оцените статью