【问题标题】:Separate an array with comma and string PHP用逗号和字符串分隔数组 PHP
【发布时间】:2018-09-05 22:02:02
【问题描述】:

我想用逗号和单词分隔一个数组。

这是我制作的代码:

$array = array( 'user1', 'user2', 'user3', 'user4', 'user5' );
$last = array_pop( $array );
$string = count( $array ) ? implode( ", ", $array ) . " and " . $last : $last;

printf( 'Authors: %s', $string );

我的代码打印这个:

作者:user1、user2、user3、user4 和 user5

我成功编写了一个代码,用逗号分解数组并搜索最后一个键并用单词“and”分隔它。

但这就是我想要的,但经过 2 多天的工作后我失败了:

作者:user1、user2、user3 和其他 2 人。

【问题讨论】:

  • 您的目标只是打印它吗?或者你想创建新数组?
  • @M4HdYaR 首先非常感谢您帮助我。其次,使用我在代码中使用的相同数组。我想打印第一个和第二个用户,然后在第三个用户之前添加单词“and”,如果数组中有更多,则添加 x 个其他用户。
  • @mickmackusa 这是数组 $array = array( 'user1', 'user2', 'user3', 'user4', 'user5' );我想从这个数组中打印:作者:user1、user2、user3 和其他 2 个。 (我想打印第一个和第二个用户并用逗号分隔它们,然后在第三个用户之前添加单词'and',如果数组中有更多则添加 x 其他。)。你现在明白了吗?
  • 你总是至少有 3 个元素吗?我们是否还需要容纳0 元素、1 元素、2 元素的可能性?

标签: php arrays implode


【解决方案1】:

虽然我一直在寻找巧妙的计算过程来处理这样的任务,但我会提供一个更简单的替代方案。 (为了记录,我讨厌写一堆if-elseif-else条件几乎和我讨厌switch-case块的冗长一样多。)对于这个狭窄的任务,我选择放弃我喜欢的数组函数并有条件地打印带有自定义分隔符的值。

虽然此解决方案在页面上的可扩展性可能最差,但它可能是最容易理解的(将代码与其生成的输出相关联)。如果这是关于“喜欢”之类的,我并没有真正看到对可扩展性的巨大需求——但我可能是错的。

密切关注 2-count 案例。我的解决方案用and 而不是, 分隔元素,这似乎更适合英语/人类。

代码:(Demo)

$arrays[] = array();
$arrays[] = array('user1');
$arrays[] = array('user1', 'user2');
$arrays[] = array('user1', 'user2', 'user3');
$arrays[] = array('user1', 'user2', 'user3', 'user4');
$arrays[] = array('user1', 'user2', 'user3', 'user4', 'user5');

foreach ($arrays as $i => $array) {
    echo "TEST $i: ";
    if (!$count = sizeof($array)) {
        echo "nobody";
    } elseif ($count == 1) {
        echo $array[0];
    } elseif ($count == 2) {
        echo "{$array[0]} and {$array[1]}";
    } elseif ($count == 3) {
        echo "{$array[0]}, {$array[1]}, and {$array[2]}";
    } else {
        echo "{$array[0]}, {$array[1]}, {$array[2]}, and " , $count - 3, " other" , ($count != 4 ? 's' : '');
    }
    echo "\n---\n";
}

输出:

TEST 0: nobody
---
TEST 1: user1
---
TEST 2: user1 and user2
---
TEST 3: user1, user2, and user3
---
TEST 4: user1, user2, user3, and 1 other
---
TEST 5: user1, user2, user3, and 2 others
---

附言相同处理的更紧凑版本:

代码:(Demo)

if (!$count = sizeof($array)) {
    echo "nobody";
} elseif ($count < 3) {
    echo implode(' and ', $array);
} else{
    echo "{$array[0]}, {$array[1]}";
    if ($count == 3) {
        echo ", and {$array[2]}";
    } else {
        echo ", {$array[2]}, and " , $count - 3, " other" , ($count != 4 ? 's' : '');
    }
}

最后,这是一种“整理”数组并将and 添加到最后一个元素的方法。我认为无论如何你旋转这个任务,都会有一定程度的卷积。

代码:(Demo)

$count = sizeof($array);
if ($count < 3) {
    echo implode(' and ', $array);
} else {
    if ($count == 3) {
        $array[2] = "and {$array[2]}";
    } else {
        $more = $count - 3;
        array_splice($array, 3, $more, ["and $more other" . ($more > 1 ? 's' : '')]);
    }
    echo implode(', ', $array);
}

在 CodeReview 期间,我实现了“pop-prepend-push”技术:https://codereview.stackexchange.com/a/255554/141885


从 PHP8 开始,match() 也可用。实现可能如下所示:(Demo)

$count = count($array);
echo match ($count) {
         0 => 'nobody',
         1 => $array[0],
         2 => implode(' and ', $array),
         3 => "{$array[0]}, {$array[1]}, and {$array[2]}",
         default => "{$array[0]}, {$array[1]}, {$array[2]}, and " . $count - 3 . " other" . ($count != 4 ? 's' : '')
     };

【讨论】:

  • 很好的答案米克:)
  • 我一直在想不同的方法来做到这一点。 ...我应该停止这样做并开始我的实际工作。 (该死的 StackOverflow 成瘾)
【解决方案2】:

这是一种方法:

首先将前两个数组元素内爆。 (array_splice 会将它们从$array 中删除。)

$string = implode(', ', array_splice($array, 0, 2));

如果有,请添加第三个。 (array_shift 也会将其从 $array 中删除。)

if ($array) {
    $string .= ', and ' . array_shift($array);
}

计算其余的并添加它们,如果有的话。

if ($n = count($array)) {
    $string .= " and $n other". ($n > 1 ? 's' : '');
    //                           conditional pluralization
}

【讨论】:

  • 我去掉了一个逗号,但这看起来不错。加 1 3v4l.org/0IXgU
  • ...如果我可以伪造一个有价值的解决方案,我仍然可以发布替代解决方案。
  • @Don't I 为 2 元素案例做了一个未提及的调整。看看我的新帖子。
【解决方案3】:

几种方法可以做到这一点,一种简单的方法:

首先,您应该获取数组中元素的数量,看看它是否超过 3。

$count = count( $array) ;

然后如果超过 3 ,你可以制作你的字符串:

if($count>3){
    $string= $array[0] . 'and' . $array[1] . 'and' . $array[2] . 'and' . ($count - 3) . "others";
}else{
    $last = array_pop( $array );
    $string = count( $array ) ? implode( ", ", $array ) . " and " . $last : $last;
    //I used exactly your code , you have several ways to do it
    //Attention ... This code may not work when your array has only one element
}
printf( 'Authors: %s', $string );

If you want to know more about PHP arrays you can use this link , a quick tutorial

Or the documentation

【讨论】:

  • 我认为打印给我的代码有问题:作者:-3others。你能添加你的完整代码吗?
  • 可以在第一个响应中使用:$string= $array[0] . ' and ' . $array[1] . ' and ' . $array[2] . ' and ' . ($count - 3) . ' others ' 变量$others不需要。只是()missing arround 到$count - 3
  • M4HdYaR 谢谢我知道您在回答中要做什么,这有助于我进一步改进您的回答。 @JérômeTeisseire 谢谢你在你发表评论之前我已经这样做了:)。
  • 此答案不会产生所需的输出。
【解决方案4】:

我建议您将您的问题视为一个可以进行单元测试的函数,以便更容易构建并且您可以灵活地解决您的解决方案。

  • 使用计数器跟踪您的数组:总计、第一个块、尾部
  • 考虑任何特殊情况,例如 2 个元素、3 个元素等。
  • 使用array_pop 获取最后一项
  • 使用array_slice 从“take N”参数中获取第一个块。
  • 根据需要进行内爆和连接以获得所需的结果

这是一个例子。

<?php

function niceAuthorsPrint(array $authors, $takeCount){

  $totalAuthors = count( $authors );
  $tailCount = $totalAuthors - $takeCount;

  $first = array_slice($authors, 0, $takeCount);

  $othersLabel = $tailCount == 1 ? 'other' : 'others';

  $string = implode( ", ", $first );

  if($tailCount > 0){
     $string .= " and " . $tailCount . ' ' . $othersLabel;      
  }

  return $string;
}

// take 3
echo niceAuthorsPrint(array( 'user1', 'user2', 'user3', 'user4', 'user5' ), 3) ."\n";

// take 4
echo niceAuthorsPrint(array( 'user1', 'user2', 'user3', 'user4', 'user5' ), 4) ."\n";

// take 5
echo niceAuthorsPrint(array( 'user1', 'user2', 'user3', 'user4', 'user5' ), 5) ."\n";

?>

将输出:

user1, user2, user3 and 2 others
user1, user2, user3, user4 and 1 other
user1, user2, user3, user4, user5

Working example here


另类

处理特殊情况和打印最后一项值的替代方法。

<?php

// array of authors, number of authors to take first
function niceAuthorsPrint(array $authors, $takeCount){

  $totalAuthors = count( $authors );

  if($totalAuthors >= 3 && $takeCount >= $totalAuthors)
  {
      $takeCount = 2;
  }

  if($totalAuthors == 2 && $takeCount >= $totalAuthors)
  {
      $takeCount = 1;
  }

  $last = array_pop($authors);

  $tailCount = $totalAuthors - $takeCount;

  $first = array_slice($authors, 0, $takeCount);

  $othersLabel = $tailCount == 1 ? $last : $tailCount . ' others';

  $string = implode( ", ", $first );

  if($tailCount > 0){
     $string .= " and " . $othersLabel;      
  }

  return $string;
}

// take 3
echo niceAuthorsPrint(array( 'user1', 'user2', 'user3', 'user4', 'user5' ), 3) ."\n";

// take 4
echo niceAuthorsPrint(array( 'user1', 'user2', 'user3', 'user4', 'user5' ), 4) ."\n";

// take 5
echo niceAuthorsPrint(array( 'user1', 'user2', 'user3', 'user4', 'user5' ), 5) ."\n";

// take original count, take first three as default
echo niceAuthorsPrint(array( 'user1', 'user2', 'user3', 'user4', 'user5' ), 5) ."\n";

// take original count, take first three as default
echo niceAuthorsPrint(array( 'user1', 'user2', 'user3'), 3) ."\n";

// take original count, take first three as default
echo niceAuthorsPrint(array( 'user1', 'user2'), 2) ."\n";

将打印:

user1, user2, user3 and 2 others
user1, user2, user3, user4 and user5
user1, user2 and 3 others
user1, user2 and 3 others
user1, user2 and user3
user1 and user2

根据您的需要随意调整。

Working code example

【讨论】:

  • 为什么要编辑答案?在进行任何编辑之前,您的回答绝对是我想要的。只是你忘记了一个东西,只有第三个用户用一个单词'and'而不是像这样的逗号分隔它:user1、user2、user3 和其他 2 个。只有当数组的计数大于 3 并且等于 3 时才会发生这种情况,那么结果将是:user1、user2 和 user3。
  • 您可以看到答案的编辑历史。这里是之前代码的链接:3v4l.org/e76Id
  • 我已经为我的项目编写了我想要的代码,我只是告诉你如何使你的答案完整以将其标记为最佳答案。如果您需要,您的旧代码可以正常工作,没有任何问题,正如我在评论中告诉您的那样。无论如何,非常感谢你的努力:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-12
相关资源
最近更新 更多