Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

array_map(null, $a, $b, $c, ...);

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

Ответ 2

Попробуйте эту функцию для создания массива массивов, подобных Pythons 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;
}

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

Ответ 3

array_combine близок.

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

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(array(1,'a'), array(2,'b'))

и следующее:

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

дает следующий результат:

array(array(1,'a','x'), array(2,'b','y'))

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

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, ...)), но слегка измененным образом (показано выше).

В общем случае:

array_map(null, $a, $b, $c);

является аналогом для 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 '<pre>';
print_r($pythonzip);
print_r($rubyzip);
echo '<pre>';

Ответ 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<$min; ++$i) {
        $result[$i] = array();
        foreach($args as $j=>$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 '<pre>'; print_r($zip_array); echo '<pre>';

Ответ 9

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

$arr1 = ['get', 'method'];
$arr2 = ['post'];

$ret = array_map(null, $arr1, $arr2);

выход:

[['get', 'method'], ['post', null]]

php function.array-map

Ответ 11

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

function make_array() { return func_get_args(); }

Ответ 12

Посвященный тем, кто считает, что это должно быть связано с 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));
}