【问题标题】:Add commas to items and with "and" near the end in PHP [duplicate]在 PHP 中将逗号添加到项目并在末尾附近添加“and”
【发布时间】:2012-01-30 15:03:58
【问题描述】:

我想为除最后一项之外的每一项添加一个逗号。最后一个必须有“and”。

第 1 项、第 2 项和第 3 项

但项目可以来自 1 +

所以如果一个项目:

项目 1

如果两个项目:

第 1 项和第 2 项

如果三个项目:

第 1 项、第 2 项和第 3 项

如果有四个项目:

第 1 项、第 2 项、第 3 项和第 4 项

等等等等

【问题讨论】:

  • 或者,您可以使用oxford comma,它同样正确(“正确”的值略有不同)。 :-)
  • 格式的可预测性如何?显然,您可以在每个空格字符处拆分项目。他们都叫 /[Ii]tem [0-9]+/ 吗?你不会想要“Item, 1, Item, 2, Item and 3”。那么……我们的输入是字符串还是数组?

标签: php loops csv


【解决方案1】:

这是一个函数;只需传递数组即可。

function make_list($items) {
    $count = count($items);

    if ($count === 0) {
        return '';
    }

    if ($count === 1) {
        return $items[0];
    }

    return @987654321@(', ', @987654322@($items, 0, -1)) . ' and ' . @987654323@($items);
}

Demo

【讨论】:

    【解决方案2】:

    minitech 一开始的解决方案很优雅,除了一个小问题,他的输出将导致:

    var_dump(makeList(array('a', 'b', 'c'))); //Outputs a, b and c
    

    但是这个列表的正确格式(有待讨论)应该是; a、b 和 c。在他的实现中,倒数第二个属性将永远不会附加“,”,因为当数组切片被传递给implode() 时,它会将其视为数组的最后一个元素。

    这是我的一个实现,并且正确地(再次讨论)格式化列表:

    class Array_Package
    {
        public static function toList(array $array, $conjunction = null)
        {
            if (is_null($conjunction)) {
                return implode(', ', $array);
            }
    
            $arrayCount = count($array);
    
            switch ($arrayCount) {
    
                case 1:
                    return $array[0];
                    break;
    
                case 2:
                    return $array[0] . ' ' . $conjunction . ' ' . $array[1];
            }
    
            // 0-index array, so minus one from count to access the
            //  last element of the array directly, and prepend with
            //  conjunction
            $array[($arrayCount - 1)] = $conjunction . ' ' . end($array);
    
            // Now we can let implode naturally wrap elements with ','
            //  Space is important after the comma, so the list isn't scrunched up
            return implode(', ', $array);
        }
    }
    
    // You can make the following calls
    
    // Minitech's function
    var_dump(makeList(array('a', 'b', 'c'))); 
    // string(10) "a, b and c"
    
    var_dump(Array_Package::toList(array('a', 'b', 'c')));
    // string(7) "a, b, c"
    
    var_dump(Array_Package::toList(array('a', 'b', 'c'), 'and'));
    string(11) "a, b, and c"
    
    var_dump(Array_Package::toList(array('a', 'b', 'c'), 'or'));
    string(10) "a, b, or c"
    

    没有反对其他解决方案,只是想提出这一点。

    【讨论】:

      【解决方案3】:

      这是一个变体,它可以选择支持有争议的Oxford Comma,并为连词(和/或)提供一个参数。注意两个项目的额外检查;在这种情况下,甚至牛津的支持者也不会使用逗号。

      function conjoinList($items, $conjunction='and', $oxford=false) {
          $count = count($items);
      
          if ($count === 0){
              return '';
          } elseif ($count === 1){
              return $items[0];
          } elseif ($oxford && ($count === 2)){
              $oxford = false;
          }
      
          return implode(', ', array_slice($items, 0, -1)) . ($oxford? ', ': ' ') . $conjunction . ' ' . end($items);
      }
      

      【讨论】:

        【解决方案4】:

        您可以用逗号分解 X - 1 个项目,并用“and”添加最后一个项目。

        【讨论】:

        • 一般来说,如果列表中只有一项呢?
        【解决方案5】:

        你可以这样做:

        $items = array("Item 1", "Item 2", "Item 3", "Item 4");
        
        $item = glueItems($items);
        
        function glueItems($items) {
            if (count($items) == 1) {
                $item = implode(", ", $items);
            } elseif (count($items) > 1)  {
                $last_item = array_pop($items);
                $item = implode(", ", $items) . ' and ' . $last_item;
            } else {
                $item = '';
            }
            return $item;
        }
        echo $item;
        

        【讨论】:

        • 如果只有一项,为什么还需要内爆?
        【解决方案6】:

        我的功能,基于这里的其他人,我觉得更加精简。也总是添加牛津逗号,因为确实没有“争议”或关于它是否正确使用的争论。

        //feed in an array of words to turn it into a written list.
        //['bacon'] turn into just 'bacon'
        //['bacon','eggs'] turns into 'bacon and eggs'
        //['bacon','eggs','ham'] turns into 'bacon, eggs, and ham'
        function writtenList($items) {
        
            //nothing, or not an array? be done with this
            if (!$items || !is_array($items)) return '';
        
            //list only one or two items long, this implosion should work fine
            if (count($items)<=2) {
                return implode(' and ',$items);
            //else take off the last item, implode the rest with just a comma and the remaining item
            } else {
                $last_item = array_pop($items);
                return implode(", ",$items).', and '.$last_item;
            }
        }
        

        【讨论】:

          【解决方案7】:

          如果是数组就用implode(...)

          例子:

          $items = array("Item 1", "Item 2", "Item 3", "Item 4");
          $items[count($items) - 1] = "and " . $items[count($items) - 1];
          $items_string = implode(", ", $items);
          
          echo $items_string;
          

          演示:http://codepad.viper-7.com/k7xISG

          【讨论】:

          • 这不会在最后一个键之前打印出请求的“and”字符串。
          • 这仍然会在最后一项之前放置一个不需要的逗号。 OP 示例显示“和”代替逗号。
          • @SimonMayer 正确的英文有一个逗号 before AND
          • @Neal:我认为现在省略逗号是可以接受的,这是用户想要的。 (是的,我也确实在“and”之前使用了逗号。)
          • 牛津逗号但错误地打印和 $items[0] 用于计数为 1 的数组
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-07-11
          • 2016-04-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-15
          • 1970-01-01
          相关资源
          最近更新 更多