如何在没有 foreach 的情况下在 PHP 中使用键和值来内爆数组
Posted
技术标签:
【中文标题】如何在没有 foreach 的情况下在 PHP 中使用键和值来内爆数组【英文标题】:How to implode array with key and value without foreach in 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/… Fastest way to implode an associative array with keys的可能重复 【参考方案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_query 和 str_replace:
str_replace('=', ':', http_build_query($array, null, ','));
内爆 1000 个元素的平均时间:0.00012930955084904
测试二:
使用 array_map 和 implode:
implode(',', array_map(
function ($v, $k)
return $k.':'.$v;
,
$array,
array_keys($array)
));
内爆 1000 个元素的平均时间:0.0004890081976675
测试三:
使用 array_walk 和 implode:
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=>$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_export 和 print_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'
等等
【讨论】:
以上是关于如何在没有 foreach 的情况下在 PHP 中使用键和值来内爆数组的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有意外匹配的情况下在 PHP 中的字符串中查找整个单词?
在 PHP 5.3 中,如何在没有严格警告的情况下在一行中获取单个元素数组中的值
如何在没有 Artisan 的情况下在 Xampp 上运行 laravel
如何在没有 iFrame 的情况下在 html 上显示来自另一台服务器的 PHP 页面?