69 votes

Existe-t-il une fonction php comme le zip de python ?

Python dispose d'une belle zip() fonction. Existe-t-il un équivalent en PHP ?

4 votes

"Le titre dit tout". Pas vraiment : que faire si je connais très bien le PHP, mais pas le Python ? Vous pourriez au moins expliquer le but et l'utilisation du "zip" de Python...

3 votes

@codeka Merci, j'ai inclus un lien vers les documents.

0 votes

@craig votre lien pour expliquer "une belle fonction zip()" dit : > Faire un itérateur qui agrège les éléments de chacun des itérables. > Elle retourne un itérateur de tuples, où le i-ième tuple contient le i-ième élément de chacune des séquences d'arguments ou itérables. L'itérateur s'arrête lorsque l'itérable d'entrée le plus court est épuisé. Avec un seul argument itérable, il retourne un itérateur de 1-tuples. Sans argument, il renvoie un itérateur vide. ... Je suis sûr à 80% que c'est la question que je cherche, mais ... vous n'avez pas aidé, mais de manière obtuse.

101voto

habnabit Points 4245

Tant que tous les tableaux sont de la même longueur, vous pouvez utiliser array_map con null comme premier argument.

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

Si certains des tableaux sont plus courts, ils seront complétés par des nuls jusqu'à la longueur du plus long, contrairement à python où le résultat retourné est la longueur du tableau le plus court.

2 votes

Tu as vraiment essayé ? array_map ne se comporte pas comme l'outil Python zip . array_map(null, array(1,2), array(3)) renvoie à array(array(1,3), array(2,null)) tandis que zip([1,2], [3]) juste des retours [(1,2)] .

7 votes

@Gumbo Bien que ce soit la méthode Ruby, plutôt que la méthode Python, je dirais que c'est assez proche pour la plupart des utilisations. Passer des tableaux de longueurs différentes à zip n'est normalement pas quelque chose que vous feriez délibérément. J'ai ajouté une explication à ce sujet dans la réponse.

1 votes

+1 En fait, c'est plutôt itertools.izip_longest(..., fillvalue=None), mais c'est très proche et reste la meilleure solution. Si vous voulez obtenir un résultat exact comme dans zip() de Python, vous pouvez utiliser array_slice(array_map(null, $a, $b), 0, min(count($a), count($b))) et obtenir exactement ce que vous voulez de la manière la plus efficace.

18voto

Jakub Hampl Points 19161

array_combine se rapproche.

Sinon, rien de tel que de le coder soi-même :

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

13voto

Gumbo Points 279147

Essayez cette fonction pour créer un tableau de tableaux similaire à celui de Python. 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;
}

Vous pouvez passer à cette fonction autant de tableaux que vous voulez avec autant d'éléments que vous voulez.

10voto

Tadeck Points 37046

Ce site fonctionne exactement comme l'outil Python zip() fonction et est également compatible avec 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);
};

Il fusionne les tableaux de la manière dont la fonction de Python zip() ne retourne pas les éléments trouvés après avoir atteint la fin du tableau le plus court.

Les suivantes :

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

donne le résultat suivant :

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

et les suivantes :

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

donne le résultat suivant :

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

Vérifiez cette démonstration pour une preuve de ce qui précède.

EDITAR : Ajout du support pour la réception d'un seul argument ( array_map se comporte différemment dans ce cas ; merci Josiah ).

1 votes

Pas exactement comme celui de Python. Comparez cet exemple en PHP a le même exemple tel qu'implémenté en Python . Zip sur un tableau unique retourne le tableau original dans votre version, un tableau de 1-tuples en Python.

0 votes

@Josiah : C'est le résultat des différences linguistiques. A savoir le comportement plutôt incohérent de array_map() : quand il est passé null en tant que premier argument, il "zappe" les autres arguments, mais s'il n'y a qu'un seul argument supplémentaire (en plus de la mention null ), il n'est pas entouré de array (comme lorsqu'il y en a deux ou plus), mais plutôt transmis tel quel. L'ajout d'une condition supplémentaire (en vérifiant la longueur de l'élément $params ) permettrait de résoudre ce problème.

1 votes

C'est très bien mais, comme c'est le cas, dire que votre fonction fonctionne exactement comme celle de Python zip() est fausse, et j'ai juste pensé que je devais le signaler au cas où quelqu'un d'autre utiliserait cette méthode et rencontrerait le même problème que moi, afin de leur épargner un temps de débogage. D'autant plus qu'il y a d'autres réponses ici qui gèrent ce cas correctement.

5voto

Tadeck Points 37046

Solution

L'adéquation de la solution zip() de très près, et en utilisant les fonctions PHP intégrées en même temps :

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
);

Pourquoi pas simple array_map(null, $a, $b, $c) appeler ?

Comme je déjà mentionné dans mon commentaire j'ai tendance à privilégier la solution de nabnabit ( array_map(null, $a, $b, ...) ), mais d'une manière légèrement modifiée (voir ci-dessus).

En général, ceci :

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

est la contrepartie de celle de Python :

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

(l'envelopper dans list() si vous voulez une liste au lieu d'un itérateur). Pour cette raison, il ne répond pas exactement à l'exigence d'imitation de zip() (à moins que tous les tableaux aient la même longueur).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X