这个数组包含一些项,我想把它转换成字符串,但是我不知道如何使最后一项在逗号之前变成&/and。
1 => coke 2=> sprite 3=> fanta
应该变成什么?
coke, sprite and fanta
这是常规的implode函数:
$listString = implode(', ', $listArrau);
有没有一个简单的方法?
适用于任意数量项目的长代码行:
echo join(' and ', array_filter(array_merge(array(join(', ', array_slice($array, 0, -1))), array_slice($array, -1)), 'strlen'));
或者,如果你真的更喜欢冗长:
$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);
关键在于这种切片、合并、过滤和连接处理所有情况,包括0、1和2项,而无需额外的if..else
语句。而且它可以折叠为一行代码。
ifs
或循环,并且可以在一个表达式中完成。这就是我称之为长行的原因。当然,您可以将其放入名为joinWithLastSeparator(array $array, $separator = ' and ')
的函数中,以便在5个月后仍知道它的作用。:o) - decezeStringUtils::implodeWithPrefixOnLast($array, ', ', ' and ');
- Nathan我不确定一行代码是解决这个问题最优雅的方法。
我写了这个一段时间了,根据需要随时使用:
/**
* 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;
}
你不必使用“and”作为连接字符串,它可以有效地处理从0到无限数量的任何内容:
// 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'));
如果您想要,很容易将其修改以包含牛津逗号:
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;
}
$yourArray = ('a', 'b', 'c');
$lastItem = array_pop($yourArray); // c
$text = implode(', ', $yourArray); // a, b
$text .= ' and '.$lastItem; // a, b and c
if (count($yourArray) > 1)
时,它的效果非常好...谢谢 :) - Enissay试试这个:
$str = array_pop($array);
if ($array)
$str = implode(', ', $array)." and ".$str;
另一个可能的简短解决方案:
$values = array('coke', 'sprite', 'fanta');
$values[] = implode(' and ', array_splice($values, -2));
print implode(', ', $values); // "coke, sprite and fanta"
它在任何数量的值下都可以正常工作。
我的首选是与Enrique的答案类似,但可选择处理牛津逗号。
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;
}
array_fill
和array_map
完成。这也是一个一行代码的解决方案(似乎许多人都喜欢它们),但为了易读性进行了格式化:$string = implode(array_map(
function ($item, $glue) { return $item . $glue; },
$array,
array_slice(array_fill(0, count($array), ', ') + ['last' => ' and '], 2)
));
虽然不是最优解,但仍然可行。
这里是演示。
我知道回答已经晚了,但这肯定是更好的做法吧?
$list = array('breakfast', 'lunch', 'dinner');
$list[count($list)-1] = "and " . $list[count($list)-1];
echo implode(', ', $list);
好的,这已经变得相当老了,但我必须说,我认为大多数答案都非常低效,需要多个implode或数组合并等复杂操作,比必要的要复杂得多。
为什么不只是:
implode(',', array_slice($array, 0, -1)) . ' and ' . array_slice($array, -1)[0]
使用正则表达式进行简单的human_implode。
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