web-dev-qa-db-fra.com

Fractionner tableau en deux tableaux par index pair ou impair

J'ai ce tableau:

$array = array(a, b, c, d, e, f, g);

Je souhaite le scinder en deux tableaux en fonction de l'index pair ou impair, comme ceci:

$odd = array(a, c, e, g);

$even = array(b, d, f);

Merci d'avance!

14
Marc Vidal Moreno

Une solution utilisant des fonctions anonymes et array_walk :

$odd = array();
$even = array();
$both = array(&$even, &$odd);
array_walk($array, function($v, $k) use ($both) { $both[$k % 2][] = $v; });

Cela sépare les éléments en un seul passage sur le tableau, mais c'est un peu "cleverish". Ce n'est pas vraiment mieux que le classique, plus prolixe

$odd = array();
$even = array();
foreach ($array as $k => $v) {
    if ($k % 2 == 0) {
        $even[] = $v;
    }
    else {
        $odd[] = $v;
    }
}
32
Jon

Utilisez array_filter :

$odd=array_filter($array, function ($input) {return $input & 1;});
$even=array_filter($array, function ($input) {return !($input & 1);});
8
Gareth

Je ne suis pas sûr que ce soit la manière la plus élégante, mais ça devrait faire un charme fou:

$odd=array();
$even=array();
$count=1;
foreach($array as $val)
{
    if($count%2==1)
    {
        $odd[]=$val;
    }
    else
    {
        $even[]=$val;
    }
    $count++;
}
3
Fluffeh
$odd = [];
$even = [];
while (count($arr)) {
    $odd[] = array_shift($arr);
    $even[] = array_shift($arr);
}
2
Martin

En tant que presque une ligne, je pense que ce sera mon préféré:

$even = $odd = array();
foreach( $array as $k => $v )  $k % 2  ?  $odd[] = $v  :  $even[] = $v;

Ou pour un petit peu plus? la vitesse:

$even = $odd = array();
foreach( $array as $k => $v )  ( $k & 1 ) === 0  ?  $even[] = $v  :  $odd[] = $v;

Variante un peu plus verbeuse:

$both = array( array(), array() );
// or, if $array has at least two elements:
$both = array();

foreach( $array as $k => $v )  $both[ $k % 2 ][] = $v;
list( $even, $odd ) = $both;

Avec array_chunk:

$even = $odd = array();
foreach( array_chunk( $array, 2 ) as $chunk ){
  list( $even[], $odd[] ) = isset( $chunk[1]) ? $chunk : $chunk + array( null, null );
  // or, to force even and odd arrays to have the same count:
  list( $even[], $odd[] ) = $chunk + array( null, null );
}

Si $ array est garanti d'avoir un nombre pair d'éléments:

$even = $odd = array();
foreach( array_chunk( $array, 2 ) as $chunk )
  list( $even[], $odd[] ) = $chunk;

PHP 5.5.0+ avec array_column:

$chunks = array_chunk( $array, 2 );
$even = array_column( $chunks, 0 );
$odd  = array_column( $chunks, 1 );

Quelque chose de similaire pour les anciennes versions PHP. Les clés seront 0,2,4,… et 1,3,5,…. Si vous n'aimez pas cela, appliquez aussi un array_values:

$even = array_intersect_key( $array, array_flip( range( 0, count( $array ), 2 )));
$odd  = array_intersect_key( $array, array_flip( range( 1, count( $array ), 2 )));

ou

$even = array_intersect_key( $array, array_fill_keys( range( 0, count( $array ), 2 ), null ));
$odd  = array_intersect_key( $array, array_fill_keys( range( 1, count( $array ), 2 ), null ));
2
biziclop

Parcourez-les et vérifiez si la clé est paire ou impaire:

$odd = array();
$even = array();
foreach( $array as $key => $value ) {
    if( 0 === $key%2) { //Even
        $even[] = $value;
    }
    else {
        $odd[] = $value;
    }
}
1
Krycke

Un

$odd = $even = array();
for ($i = 0, $l = count($array ); $i < $l;) { // Notice how we increment $i each time we use it below, by two in total
    $even[] = $array[$i++];
    if($i < $l)
    {
       $odd[] = $array[$i++];
    }
}

Deux

$odd = $even = array();
foreach (array_chunk($array , 2) as $chunk) {
    $even[] = $chunk[0];
    if(!empty( $chunk[1]))
    {
       $odd[] = $chunk[1];
    }
}
1
Clyde Lobo

Sur la base de la deuxième variante de @ Jon, j’ai fait ceci après pour une utilisation avec PHP moteur de template Smarty v3 . Ceci est pour afficher des news/blog avec un modèle de modèle à une ou deux colonnes.

Après la requête MySql, je ferai le code suivant:

if(sizeof($results) > 0) {
    $data = array();
    foreach($results as $k => $res) {
        if($k % 2 == 0) {
            $res["class"] = "even";
            $data["all"][] = $data["even"][] = $res;
        }
        else {
            $res["class"] = "odd";
            $data["all"][] = $data["odd"][] = $res;
        }
    }
}

J'obtiens un tableau de 3 sous-tableaux (y compris les classes pair/impair) avec la syntaxe d'utilisation Smarty:

  1. tous les articles {foreach $data.all as $article}...{/foreach}
  2. éléments impairs uniquement {foreach $data.odd as $article}...{/foreach}
  3. même les articles seulement {foreach $data.even as $article}...{/foreach}

J'espère que ça aide certaines personnes ...

1
Meloman