web-dev-qa-db-fra.com

Implode tableau avec "," et ajoute "et" avant le dernier élément

Ce tableau contient une liste d'éléments, je veux le transformer en chaîne mais je ne sais pas comment faire en sorte que le dernier élément ait un &/et au lieu d'un coma.

1 => coke 2=> Sprite 3=> fanta

devraient devenir 

coke, Sprite and fanta

C'est la fonction régulière implode:

$listString = implode(', ',$listArrau );

Quel est un moyen facile de le faire?

53
lisovaccaro

Un palangrier qui fonctionne avec n'importe quel nombre d'articles:

echo join(' and ', array_filter(array_merge(array(join(', ', array_slice($array, 0, -1))), array_slice($array, -1)), 'strlen'));

Ou, si vous vraiment préférez le verbosité:

$last  = array_slice($array, -1);
$first = join(', ', array_slice($array, 0, -1));
$both  = array_filter(array_merge(array($first), $last), 'strlen');
echo join(' and ', $both);

Le fait est que cette opération de découpage, de fusion, de filtrage et de jonction traite correctement les commandes all cases, y compris les éléments 0, 1 et 2, sans instruction supplémentaire if..else. Et il se trouve être pliable en une ligne.

93
deceze

Je ne suis pas sûr qu'un liner soit la solution la plus élégante à ce problème.

Je l'ai écrit il y a un moment et le dépose au besoin:

/**
 * Join a string with a natural language conjunction at the end. 
 * https://Gist.github.com/angry-dan/e01b8712d6538510dd9c
 */
function natural_language_join(array $list, $conjunction = 'and') {
  $last = array_pop($list);
  if ($list) {
    return implode(', ', $list) . ' ' . $conjunction . ' ' . $last;
  }
  return $last;
}

Vous n'avez pas à utiliser "et" comme chaîne de jointure, elle est efficace et fonctionne avec des valeurs allant de 0 à un nombre illimité d'éléments:

// null
var_dump(natural_language_join(array()));
// string 'one'
var_dump(natural_language_join(array('one')));
// string 'one and two'
var_dump(natural_language_join(array('one', 'two')));
// string 'one, two and three'
var_dump(natural_language_join(array('one', 'two', 'three')));
// string 'one, two, three or four'
var_dump(natural_language_join(array('one', 'two', 'three', 'four'), 'or'));
58
Angry Dan

Vous pouvez afficher le dernier élément, puis le joindre au texte:

$yourArray = ('a', 'b', 'c');
$lastItem = array_pop($yourArray); // c
$text = implode(', ', $yourArray); // a, b
$text .= ' and '.$lastItem; // a, b and c
24
JercSi

Essaye ça:

$str = array_pop($array);
if ($array)
    $str = implode(', ', $array)." and ".$str;
14
Enrique

Une autre solution courte possible:

$values = array('coke', 'Sprite', 'fanta');

$values[] = implode(' and ', array_splice($values, -2));
print implode(', ', $values);  // "coke, Sprite and fanta"

Cela fonctionne bien avec n'importe quel nombre de valeurs.

3
VisioN

Je sais que je suis trop tard pour trouver la réponse, mais c'est sûrement une meilleure façon de le faire

$list = array('breakfast', 'lunch', 'dinner');
$list[count($list)-1] = "and " . $list[count($list)-1];
echo implode(', ', $list);
2
Jack B

Mon préféré, similaire à la réponse d'Enrique, mais gère éventuellement la virgule Oxford.

public static function listifyArray($array,$conjunction='and',$oxford=true) {
    $last = array_pop($array);
    $remaining = count($array);
    return ($remaining ?
        implode(', ',$array) . (($oxford && $remaining > 1) ? ',' : '') . " $conjunction "
        : '') . $last;
}
0
JJ Wright

Simple human_implode using regex.

function human_implode($glue = ",", $last = "y", $elements = array(), $filter = null){
    if ($filter) {
        $elements = array_map($filter, $elements);
    }

    $str = implode("{$glue} ", $elements);

    if (count($elements) == 2) {
        return str_replace("{$glue} ", " {$last} ", $str);
    }

   return preg_replace("/[{$glue}](?!.*[{$glue}])/", " {$last}", $str);
}

print_r(human_implode(",", "and", ["Joe","Hugh", "Jack"])); // => Joe, Hugh and Jack
0
uruapanmexicansong

OK, donc ça commence à être assez vieux, mais je dois dire que je pense que la plupart des réponses sont très inefficaces avec de multiples implodes ou des fusions de tableaux et des choses comme ça, toutes beaucoup plus complexes que l’OMI nécessaire.

Pourquoi pas simplement:

implode(',', array_slice($array, 0, -1)) . ' and ' . array_slice($array, -1)[0]
0
greenbutterfly

C’est assez ancien à ce stade, mais j’ai pensé que cela ne pouvait pas nuire d’ajouter ma solution à la pile. C'est un peu plus de code que d'autres solutions, mais cela me convient.

Je voulais quelque chose avec un peu de flexibilité. J'ai donc créé une méthode utilitaire qui permet de définir le séparateur final (afin de pouvoir utiliser une esperluette, par exemple) et d'utiliser une virgule Oxford. Il gère également correctement les listes avec 0, 1 et 2 éléments (ce que peu de réponses ne font pas ici)

$androidVersions = ['Donut', 'Eclair', 'Froyo', 'Gingerbread', 'Honeycomb', 'Ice cream sandwich', 'Jellybean', 'Kit Kat', 'Lollipop', 'Marshmallow'];

echo joinListWithFinalSeparator(array_slice($androidVersions, 0, 1)); // Donut
echo joinListWithFinalSeparator(array_slice($androidVersions, 0, 2)); // Donut and Eclair
echo joinListWithFinalSeparator($androidVersions); // Donut, Eclair, Froyo, Gingerbread, Honeycomb, Ice cream sandwich, Jellybean, Kit Kat, Lollipop, and Marshmallow
echo joinListWithFinalSeparator($androidVersions, '&', false); // Donut, Eclair, Froyo, Gingerbread, Honeycomb, Ice cream sandwich, Jellybean, Kit Kat, Lollipop & Marshmallow

function joinListWithFinalSeparator(array $arr, $lastSeparator = 'and', $oxfordComma = true) {
    if (count($arr) > 1) {
        return sprintf(
            '%s%s %s %s', 
            implode(', ', array_slice($arr, 0, -1)),
            $oxfordComma && count($arr) > 2 ? ',':'',
            $lastSeparator ?: '', 
            array_pop($arr)
        );
    }

    // not a fan of this, but it's the simplest way to return a string from an array of 0-1 items without warnings
    return implode('', $arr);
}
0
Josh Janusch

Je viens de coder cela en fonction des suggestions de cette page. Je suis parti dans mon pseudo-code dans les commentaires au cas où quelqu'un en aurait besoin. Mon code diffère des autres ici car il traite différemment des tableaux de tailles différentes et utilise la notation de virgule Oxford pour les listes de trois ou plus.

    /**
     * Create a comma separated list of items using the Oxford comma notation.  A
     * single item returns just that item.  2 array elements returns the items
     * separated by "and".  3 or more items return the comma separated list.
     *
     * @param array $items Array of strings to list
     * @return string List of items joined by comma using Oxford comma notation
     */
    function _createOxfordCommaList($items) {
        if (count($items) == 1) {
            // return the single name
            return array_pop($items);
        }
        elseif (count($items) == 2) {
            // return array joined with "and"
            return implode(" and ", $items);
        }
        else {
            // pull of the last item
            $last = array_pop($items);

            // join remaining list with commas
            $list = implode(", ", $items);

            // add the last item back using ", and"
            $list .= ", and " . $last;

            return $list;
        }
    }
0
zkent

Une autre solution, bien que légèrement plus verbeuse, que j’ai proposée. Dans ma situation, je voulais mettre les mots du tableau au pluriel, cela ajoutera donc un "s" à la fin de chaque élément (à moins que le mot se termine déjà par 's': 

$models = array("F150","Express","CR-V","Rav4","Silverado");
foreach($models as $k=>$model){ 
    echo $model;
    if(!preg_match("/s|S$/",$model)) 
        echo 's'; // add S to end (if it doesn't already end in S)
    if(isset($models[$k+1])) { // if there is another after this one.
        echo ", "; 
        if(!isset($models[$k+2])) 
            echo "and "; // If this is next-to-last, add  ", and" 
        }
    }
}

les sorties:

F150s, Express, CR-Vs, Rav4s, and Silverados
0
Alex Russell

Essaye ça,

<?php
$listArray = array("coke","Sprite","fanta");

foreach($listArray as $key => $value)
{
 if(count($listArray)-1 == $key)
  echo "and " . $value;
 else if(count($listArray)-2 == $key)
  echo $value . " ";
 else
  echo $value . ", ";
}
?>
0
planet x

Cela peut être fait avec array_fill et array_map . C'est aussi un one-liner (il semble que beaucoup les apprécient)), mais formaté pour la lisibilité

$string = implode(array_map(
    function ($item, $glue) { return $item . $glue; }, 
    $array,
    array_slice(array_fill(0, count($array), ', ') + ['last' => ' and '], 2)
));

Pas la solution la plus optimale, mais néanmoins.

Voici la démo .

0
sevavietl

essaye ça

$arr = Array("coke","Sprite","fanta");
$str = "";
$lenArr = sizeof($arr);
for($i=0; $i<$lenArr; $i++)
{
    if($i==0)
        $str .= $arr[$i];
    else if($i==($lenArr-1))
        $str .= " and ".$arr[$i];
    else
        $str .= " , ".$arr[$i];
}
print_r($str);
0
Astha