【问题标题】:How to implode array with key and value without foreach in PHP如何在没有 foreach 的情况下在 PHP 中使用键和值来内爆数组
【发布时间】:2012-07-10 18:15:38
【问题描述】:

没有 foreach, 我怎样才能把这样的数组变成这样

array("item1"=>"object1", "item2"=>"object2",......."item-n"=>"object-n");

到这样的字符串

item1='object1', item2='object2',.... item-n='object-n'

我已经想到了implode(),但它并没有用它来内爆密钥。

如果需要foreach,是否可以不嵌套foreach?

编辑:我改变了字符串


EDIT2/更新: 这个问题是很久以前被问到的。那时,我想将所有内容写在一行中,因此我将使用三元运算符并嵌套内置函数调用以支持 foreach。那不是一个好习惯!编写可读的代码,是否简洁并不重要。

在这种情况下:将 foreach 放在函数中将比编写单行代码更具可读性和模块化(尽管所有答案都很棒!)。

【问题讨论】:

  • foreach 需要如何嵌套?
  • 你在尝试什么?为什么会有这些限制?
  • 这是我正在构建的 Web 应用程序的数据库类,我不希望它看起来很乱,因为它已经填充了一堆 foreach 和 for-loop
  • 这个选择的答案是您要求的方法,但是应该注意它非常慢,如果您通过数据库存储此信息,它将大大优于循环和这个只使用 json_encode。附件 A:willem.stuursma.name/2010/11/22/…

标签: php arrays string implode


【解决方案1】:

我会使用serialize()json_encode()

虽然它不会为您提供所需的确切结果字符串,但以后编码/存储/检索/解码会容易得多。

【讨论】:

    【解决方案2】:

    改变

    -    return substr($result, (-1 * strlen($glue)));
    +    return substr($result, 0, -1 * strlen($glue));
    

    如果你想在没有最后一个 $glue 的情况下重新调整整个字符串

    function key_implode(&$array, $glue) {
        $result = "";
        foreach ($array as $key => $value) {
            $result .= $key . "=" . $value . $glue;
        }
        return substr($result, (-1 * strlen($glue)));
    }
    

    及用法:

    $str = key_implode($yourArray, ",");
    

    【讨论】:

    • 我知道这是每次都编写 foreach 循环的有效替代方法。赞成 ;)
    【解决方案3】:

    你可以使用http_build_query,像这样:

    <?php
      $a=array("item1"=>"object1", "item2"=>"object2");
      echo http_build_query($a,'',', ');
    ?>
    

    输出:

    item1=object1, item2=object2 
    

    Demo

    【讨论】:

    • 能不能把object1变成'object1'
    • 从未使用过http_build_query的其他参数。
    • 当心字符串编码!如果您不构建 URL,您可能不希望在数组键和值上使用它
    • @Matteo 您可以将http_build_query 包裹在urldecode 中以避免它。
    • 天才解决方案。这就是我对 am assoc 数组的调试输出所需要的全部内容。
    【解决方案4】:

    还有另一种方式:

    $input = array(
        'item1'  => 'object1',
        'item2'  => 'object2',
        'item-n' => 'object-n'
    );
    
    $output = implode(', ', array_map(
        function ($v, $k) {
            if(is_array($v)){
                return $k.'[]='.implode('&'.$k.'[]=', $v);
            }else{
                return $k.'='.$v;
            }
        }, 
        $input, 
        array_keys($input)
    ));
    

    或:

    $output = implode(', ', array_map(
        function ($v, $k) { return sprintf("%s='%s'", $k, $v); },
        $input,
        array_keys($input)
    ));
    

    【讨论】:

    • 这个方法是作者所要求的,但应该注意的是它非常慢,如果你通过数据库存储这些信息,它会大大优于循环和这个只使用 json_encode。附件 A:willem.stuursma.name/2010/11/22/…
    • 这里的链接似乎都不起作用了,它们都是echo "Hello, World!"; 我应该看到这些函数的代码示例吗?
    • 这个方法很容易根据自己的需求定制。
    • 我使用这种方法来构建选择选项并填充所选选项,并且由于两个数组的大小必须相同,您可以对第二个数组执行类似的操作。 array_fill(0, $input, 'selected-value-you want-to-check-against'); 这将为所有行生成具有单个值的相同大小的数组。
    【解决方案5】:

    使用array_walk

    $a = array("item1"=>"object1", "item2"=>"object2","item-n"=>"object-n");
    $r=array();
    array_walk($a, create_function('$b, $c', 'global $r; $r[]="$c=$b";'));
    echo implode(', ', $r);
    

    IDEONE

    【讨论】:

    • 我喜欢 array_walk 方法,但我不明白为什么人们建议使用 create_function 而不是只使用匿名函数?
    • @Rikki 兼容性!
    • 啊!我没有意识到这是一个 PHP4 的东西!
    • @Rikki 。它是 PHP 5.3 之前的东西。 Anonymous function 首次出现在 PHP 5.3
    • 但是它是在 PHP 4.0.1 中引入的,所以是 PHP4 的东西。语义...在次要版本更新中添加与匿名函数一样重要的功能是很奇怪的。
    【解决方案6】:

    用于调试目的。递归将嵌套数组的数组写入字符串。 用过foreach。函数存储国家语言字符。

    function q($input)
    {
        $glue = ', ';
        $function = function ($v, $k) use (&$function, $glue) {
            if (is_array($v)) {
                $arr = [];
                foreach ($v as $key => $value) {
                    $arr[] = $function($value, $key);
                }
                $result = "{" . implode($glue, $arr) . "}";
            } else {
                $result = sprintf("%s=\"%s\"", $k, var_export($v, true));
            }
            return $result;
        };
        return implode($glue, array_map($function, $input, array_keys($input))) . "\n";
    }
    

    【讨论】:

      【解决方案7】:

      我进行了测量(100000 次迭代),用什么最快的方法来粘合关联数组?

      目标:获取一行1000个项目,格式如下:“key:value,key2:value2”

      我们有数组(例如):

      $array = [
          'test0' => 344,
          'test1' => 235,
          'test2' => 876,
          ...
      ];
      

      测试一:

      使用 http_build_querystr_replace

      str_replace('=', ':', http_build_query($array, null, ','));
      

      内爆 1000 个元素的平均时间:0.00012930955084904

      测试二:

      使用 array_mapimplode

      implode(',', array_map(
              function ($v, $k) {
                  return $k.':'.$v;
              },
              $array,
              array_keys($array)
          ));
      

      内爆 1000 个元素的平均时间:0.0004890081976675

      测试三:

      使用 array_walkimplode

      array_walk($array,
              function (&$v, $k) {
                  $v = $k.':'.$v;
              }
          );
      implode(',', $array);
      

      内爆 1000 个元素的平均时间:0.0003874126245348

      测试四:

      使用foreach

          $str = '';
          foreach($array as $key=>$item) {
              $str .= $key.':'.$item.',';
          }
          rtrim($str, ',');
      

      内爆 1000 个元素的平均时间:0.00026632803902445

      我可以得出结论,粘合数组的最佳方法 - 使用 http_build_query 和 str_replace

      【讨论】:

      • $s = ''; foreach ($array as $k=&gt;$v) { if ($s !== null) { $s .= ','; } $s .= "{$k}:{$v}"; } 优于所有其他人。
      • http_build_query bench 缺少 urldecode 以便与其他人进行比较。
      • 另一种选择:substr(str_replace('"', '', json_encode($headers)), 1, -1);
      • 注意:如果有空格,它会改变你的值。 http_build_query 用加号 (+ ) 字符替换空格。
      • 我刚刚测试了http_build_query+urldecode vs implode。 Implode 的速度提高了 10 倍。
      【解决方案8】:

      您也可以使用 PHP 的 array_reduce

      $a = ['Name' => 'Last Name'];
      
      function acc($acc,$k)use($a){ return $acc .= $k.":".$a[$k].",";}
      
      $imploded = array_reduce(array_keys($a), "acc");
      

      【讨论】:

      • 很好的建议!
      【解决方案9】:

      用于从数组中创建 mysql where 条件

      $sWheres = array('item1'  => 'object1',
                       'item2'  => 'object2',
                       'item3'  => 1,
                       'item4'  => array(4,5),
                       'item5'  => array('object3','object4'));
      $sWhere = '';
      if(!empty($sWheres)){
          $sWhereConditions = array();
          foreach ($sWheres as $key => $value){
              if(!empty($value)){
                  if(is_array($value)){
                      $value = array_filter($value); // For remove blank values from array
                      if(!empty($value)){
                          array_walk($value, function(&$item){ $item = sprintf("'%s'", $item); }); // For make value string type 'string'
                          $sWhereConditions[] = sprintf("%s in (%s)", $key, implode(', ', $value));
                      }
                  }else{
                      $sWhereConditions[] = sprintf("%s='%s'", $key, $value);
                  }
              }
          }
          if(!empty($sWhereConditions)){
              $sWhere .= "(".implode(' AND ', $sWhereConditions).")";
          }
      }
      echo $sWhere;  // (item1='object1' AND item2='object2' AND item3='1' AND item4 in ('4', '5') AND item5 in ('object3', 'object4'))
      

      【讨论】:

        【解决方案10】:

        这是一个简单的例子,使用类:

        $input = array(
            'element1'  => 'value1',
            'element2'  => 'value2',
            'element3' =>  'value3'
        );
        
        echo FlatData::flatArray($input,', ', '=');
        
        class FlatData
        {
        
            public static function flatArray(array $input = array(), $separator_elements = ', ', $separator = ': ')
            {
                $output = implode($separator_elements, array_map(
                    function ($v, $k, $s) {
                        return sprintf("%s{$s}%s", $k, $v);
                    },
                    $input,
                    array_keys($input),
                    array_fill(0, count($input), $separator)
                ));
              return $output;
            }
        
        }
        

        【讨论】:

          【解决方案11】:

          还有 var_exportprint_r 更为人所知,用于打印调试输出,但这两个函数都可以采用可选参数来返回字符串。

          使用问题中的示例作为数据。

          $array = ["item1"=>"object1", "item2"=>"object2","item-n"=>"object-n"];
          

          使用print_r将数组转成字符串

          这将输出一个人类可读的变量表示。

          $string = print_r($array, true);
          echo $string;
          

          将输出:

          Array
          (
              [item1] => object1
              [item2] => object2
              [item-n] => object-n
          )
          

          使用var_export将数组转成字符串

          这将输出变量的 php 字符串表示形式。

          $string = var_export($array, true);
          echo $string;
          

          将输出:

          array (
            'item1' => 'object1',
            'item2' => 'object2',
            'item-n' => 'object-n',
          )
          

          因为它是有效的 php,我们可以对其进行评估。

          eval('$array2 = ' . var_export($array, true) . ';');
          var_dump($array2 === $array);
          

          输出:

          bool(true)
          

          【讨论】:

            【解决方案12】:

            使用explode从任何字符串中获取数组总是可以的,因为数组总是标准结构。

            但是关于数组到字符串,有什么理由在代码中使用预定义的字符串吗?而字符串应该以任何格式使用!

            foreach 的好处是您可以根据需要创建字符串! 我建议仍然使用 foreach 安静可读且干净。

            $list = array('a'=>'1', 'b'=>'2', 'c'=>'3');
            
            $sql_val = array();
            foreach ($list as $key => $value) {
                $sql_val[] = "(" . $key . ", '" . $value . "') ";
            }
            $sql_val = implode(', ', $sql_val);
            

            结果:

            (a, '1') , (b, '2') , (c, '3') 
            

            |

            (a: '1') , (b: '2') , (c: '3') 
            

            |

            a:'1' , b:'2' , c:'3' 
            

            等等

            【讨论】:

              猜你喜欢
              • 2023-01-13
              • 1970-01-01
              • 2015-02-24
              • 2016-01-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多