php 用“,”内爆一个数组,并在最后一项之前添加“和”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8586141/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Implode an array with ", " and add "and " before the last item
提问by lisovaccaro
This array holds a list of items, and I want to turn it into a string, but I don't know how to make the last item have a &/and before it instead of a comma.
这个数组包含一个项目列表,我想把它变成一个字符串,但我不知道如何让最后一个项目在它之前有一个 &/and 而不是逗号。
1 => coke 2=> sprite 3=> fanta
should become
应该成为
coke, sprite and fanta
This is the regular implode function:
这是常规的内爆函数:
$listString = implode(', ', $listArrau);
What's an easy way to do it?
有什么简单的方法可以做到?
回答by deceze
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 reallyprefer 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 allcases, including 0, 1 and 2 items, correctly without extra if..else
statements. And it happens to be collapsible into a one-liner.
关键是这种切片、合并、过滤和连接可以正确处理所有情况,包括 0、1 和 2 项,而无需额外的if..else
语句。它恰好可以折叠成一个单线。
回答by Angry Dan
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:
您不必使用“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'));
回答by JercSi
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
回答by Enrique
Try this:
尝试这个:
$str = array_pop($array);
if ($array)
$str = implode(', ', $array)." and ".$str;
回答by VisioN
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 fine with any number of values.
它适用于任意数量的值。
回答by Hyman B
I know im way to late for the answer, but surely this is a better way of doing it?
我知道我的答案迟到了,但这肯定是一种更好的方法吗?
$list = array('breakfast', 'lunch', 'dinner');
$list[count($list)-1] = "and " . $list[count($list)-1];
echo implode(', ', $list);
回答by JJ Wright
My go-to, similar to Enrique's answer, but optionally handles 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;
}
回答by uruapanmexicansong
Simple human_implodeusing regex.
使用正则表达式的简单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", "Hyman"])); // => Joe, Hugh and Hyman
回答by sevavietl
This can be done with array_fill
and array_map
. It is also a one-liner (seems that many enjoy them)), but formated for readability:
这可以通过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)
));
Not the most optimal solution, but nevertheless.
不是最佳解决方案,但仍然如此。
Here is the demo.
这是演示。
回答by Alex Russell
Another, although slightly more verbose, solution I came up with. In my situation, I wanted to make the words in the array plural, so this will add an "s" to the end of each item (unless the word already ends in 's':
我想出了另一个虽然稍微冗长的解决方案。在我的情况下,我想让数组中的单词复数,所以这会在每个项目的末尾添加一个“s”(除非单词已经以“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