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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 05:02:11  来源:igfitidea点击:

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

phparrays

提问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..elsestatements. 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_filland 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