Implode an array with ", " and add "and " before the last item

You can pop last item and then join it with the text:

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

I'm not sure that a one liner is the most elegant solution to this problem.

I wrote this a while ago and drop it in as required:

/**
 * 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 don't have to use "and" as your join string, it's efficient and works with anything from 0 to an unlimited number of items:

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

It's easy to modify to include an Oxford comma if you want:

function natural_language_join( array $list, $conjunction = 'and' ) : string {
    $oxford_separator = count( $list ) == 2 ? ' ' : ', ';
    $last = array_pop( $list );

    if ( $list ) {
        return implode( ', ', $list ) . $oxford_separator . $conjunction . ' ' . $last;
    }

    return $last;
}

A long-liner that works with any number of items:

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

Or, if you really prefer the verboseness:

$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 point is that this slicing, merging, filtering and joining handles all cases, including 0, 1 and 2 items, correctly without extra if..else statements. And it happens to be collapsible into a one-liner.

Tags:

Php

Arrays