在PHP中如何在没有foreach的情况下内爆带有键和值的数组


How to implode array with key and value without foreach in PHP

如果没有foreach,我怎么能转动这样的阵列

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

到像这个这样的字符串

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

我已经考虑过implode()了,但它并没有破坏密钥。

如果前臂是必要的,是否可以不嵌套前臂?

编辑:我更改了字符串


编辑2/更新:这个问题是很久以前提出的。当时,我想把所有内容都写在一行中,所以我会使用三元运算符和嵌套函数调用,以支持foreach。这不是一个好的做法!编写可读的代码,简洁与否并不重要。

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

您可以使用http_build_query,如下所示:

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

输出:

item1=object1, item2=object2 

演示

和另一种方式:

$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)
));

我进行了测量(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_map内爆

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

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

第三次测试:

使用array_walk内爆

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

我会使用serialize()json_encode()

虽然它不会给你想要的确切结果字符串,但以后编码/存储/检索/解码会容易得多。

使用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

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

更改

-    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, ",");

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

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";
}

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

$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;
    }
}

用于从数组创建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'))

简称:

$string = implode('; ', array_map(fn($k, $v) => "$k=$v", array_keys($array), $array));

使用爆炸从任何字符串中获取数组总是可以的,因为数组是一个始终处于标准结构中的数组。

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

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' 

等等。

我一直在寻找这个问题的解决方案,我知道它已经有10年的历史了,但在页面的一半,我想:为什么不在json编码上替换字符串呢。它将使您能够轻松访问如何配置字符串。此外,它是一个避免(foreach)循环的oneliner。

它看起来像这样:

$wrapperAttributesString = str_replace(['{"' , '"}', '":', '","'],['' , '', '=', ' '], json_encode($wrapperAttributes));

所以,从根本上讲,这里发生的是:

$wrapperAttributes['class'] = 'hi__stack--overflow';
$wrapperAttributes['style'] = 'overflow: stack; ';
$wrapperAttributes['id']    = 'oneliner_array_with_keys_tostring_attributes';
//if we were to json encode this array: it would result in this:
// {"class":"hi__stack--overflow","style":"overflow: stack; ","id":"oneliner_array_with_keys_tostring_attributes"}

现在strreplace的第一个参数采用了一个带有findwhat的数组,第二个参数则是一个替换为的数组。的确如此:

查找{〃并且什么都不替换;

find}";并以零取代;

查找":并替换为=;

查找"并替换为";关闭属性和空间以链接下一个

输出将是

class=";hi__stack—溢出";style=";溢出:堆栈"id=";oneliner_array_with_keys_string_attributes"

现在,如果您希望使用逗号分隔而不是空格分隔的字符串,只需将最后一个替换更改为find"quot;带有","

输出将变成

class=";hi__stack—溢出";,style=";溢出:堆栈;&";,id=";oneliner_array_with_keys_string_attributes

请注意,这对于html属性来说可能是安全的(考虑到值永远不应该有双qute),但我明确不会在值可以与替换具有相同组合的情况下使用它。

这是我的第一篇帖子,所以,如果你有任何反馈的话。请随时告诉我,如果我无意中没有遵守任何标准,请告诉我,我会尽快更改:)

此外,如果问题已经过时,并且不再请求解决方案,我只是发现自己需要打印一个数组来进行调试(抛出异常并显示导致问题的数组)。

出于这个原因,我还是提出了我的简单解决方案(有一行,就像最初问的那样):

$array = ['a very' => ['complex' => 'array']];
$imploded = var_export($array, true);

这将返回导出的var,而不是直接将其打印在屏幕上,并且var$explombed将包含完整的导出。