Embed an array with "," and add "and" before the last element

This array contains a list of elements, and I want to turn it into a string, but I do not know how to make the last element have the & / character and instead of a comma in front of it.

1 => coke 2=> sprite 3=> fanta 

should become

 coke, sprite and fanta 

This is a common blast function:

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

What is an easy way to do this?

+61
arrays php
Dec 21 '11 at 7:01
source share
16 answers

Long-term work that works with any number of elements:

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

Or, if you really prefer verbosity:

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

The fact is that this slicing, merging, filtering and combining handle all cases, including 0, 1 and 2 elements, without additional if..else statements. And this happens to be collapsed into a single line.

+96
Dec 21 2018-11-11T00:
source share

I am not sure that one liner is the most elegant solution to this problem.

I wrote this a while ago and put it as needed:

 /** * 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; } 

You do not need to use "and" as your connection string, it is efficient and works with anything: from 0 to an unlimited number of elements:

 // 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')); 
+68
Jul 31. '14 at 11:38
source share

You can put the last element and then attach it to the text:

 $yourArray = ('a', 'b', 'c'); $lastItem = array_pop($yourArray); // c $text = implode(', ', $yourArray); // a, b $text .= ' and '.$lastItem; // a, b and c 
+26
Dec 21 '11 at 7:05
source share

Try the following:

 $str = array_pop($array); if ($array) $str = implode(', ', $array)." and ".$str; 
+15
Nov 26 '13 at 12:33
source share

Another possible short solution:

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

It works great with any number of values.

+3
Feb 10 '14 at 17:44
source share

I know they need to answer late, but of course, is this the best way to do this?

 $list = array('breakfast', 'lunch', 'dinner'); $list[count($list)-1] = "and " . $list[count($list)-1]; echo implode(', ', $list); 
+2
Aug 15 2018-12-12T00:
source share

My transition, similar to Enrique's answer, but optionally processes the Oxford comma.

 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; } 
+1
Jan 19 '18 at 16:51
source share

Try it,

 <?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
Dec 21 '11 at 7:10
source share

try it

 $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
Dec 21 '11 at 7:13
source share

I just encoded it based on the sentences on this page. I left comments in my pseudo-code in case someone needed it. My code is different from the others here because it handles the different sizes of arrays differently and uses Oxford comma notation for lists of three or more.

  /** * 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
Sep 24 '15 at 15:18
source share

This is a rather old moment, but I thought that it could not hinder to add my solution to the heap. This is a bit more code than other solutions, but I'm fine with that.

I need something with some flexibility, so I created a utility method that allows you to set what the final delimiter should be (for example, you could use an ampersand) and use or not use the Oxford comma. It also correctly processes lists with 0, 1, and 2 points (something doesn’t do a lot of answers here)

 $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 the simplest way to return a string from an array of 0-1 items without warnings return implode('', $arr); } 
0
Jan 05 '16 at 21:51
source share

OK, so this is getting pretty old, but I have to say that most of the answers are very inefficient with multiple merges of modules or arrays, etc., everything is much more complicated than the necessary IMO.

Why not just:

 implode(',', array_slice($array, 0, -1)) . ' and ' . array_slice($array, -1)[0] 
0
Jun 10 '17 at 10:22
source share

Simple human_implode using regular expressions.

 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
Feb 09 '18 at 17:22
source share

This can be done using array_fill and array_map . This is also a one-liner (it seems that many people like them)), but formatted for readability:

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

Not the best solution, but nonetheless.

Here is a demo .

0
Feb 09 '18 at 20:33
source share

Another, albeit somewhat more detailed, solution that I came up with. In my situation, I wanted to make the plural words plural, so this would add β€œs” to the end of each element (unless the word ends with β€œ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" } } } 

outputs:

 F150s, Express, CR-Vs, Rav4s, and Silverados 
0
Feb 11 '19 at 16:14
source share

It destroys the solution faster and works with huge arrays (1M + elements). The only drawback of both solutions is poor interaction with the number 0 in less than three array elements due to the use of array_filter.

 echo implode(' and ', array_filter(array_reverse(array_merge(array(array_pop($array)), array(implode(', ',$array)))))); 
-one
Feb 16 '12 at 12:50
source share



All Articles