如何在PHP中不使用foreach就用键和值对数组进行内爆


111

没有foreach,我怎么能这样一个数组

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

像这样的字符串

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

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

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

编辑:我已经更改了字符串


EDIT2 / UPDATE: 这个问题是很久以前提出的。当时,我想将所有内容写在一行中,因此我将使用三元运算符并嵌套内置的函数调用以支持foreach。那不是一个好习惯!编写可读的代码(无论是否简洁)都无关紧要。

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


怎么嵌套foreach是必要的?
Shubham

你在想什么 为什么会有这些限制?
马达拉的鬼魂

这是我正在构建的用于Web应用程序的数据库类,我不希望它看起来凌乱,因为它已经填充了一堆foreach和for-loop
tom91136

1
选择的答案是您所要求的方法,但是应注意,它的速度非常慢,并且如果您通过数据库存储此信息,则这将大大优于循环,而仅使用json_encode会更好。展品答:willem.stuursma.name/2010/11/22/...
案例

Answers:


187

另一种方式:

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

6
该方法正是作者所要求的,但应注意,它的速度非常慢,并且如果您通过数据库存储此信息,则这将大大优于循环和仅使用json_encode。展品答:willem.stuursma.name/2010/11/22/...
案例

这里的所有链接似乎都不再起作用,它们全部都echo "Hello, World!";应该我看到这些函数的代码示例吗?
费利克斯Gagnon的-格雷尼尔

这种方法很容易根据自己的需求进行定制。
Kabir Hossain

我使用这种方法来构建选择选项并填充选择的选项,并且由于两个数组的大小必须相同,因此您可以对第二个数组执行类似的操作。array_fill(0, $input, 'selected-value-you want-to-check-against');这将为所有行生成具有单个值的相同大小的数组。
krasenslavov

186

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

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

输出:

item1=object1, item2=object2 

演示版


5
从未使用的其他参数http_build_query
Shiplu Mokaddim'7

16
+1地狱啊我喜欢寻找善良的小金块这样:)

8
当心字符串编码如果不建立一个URL,也许你不希望它在你的数组键和值!
利玛窦

8
@Matteo你可以用http_build_queryurldecode以避免它。
2014年

3
天才解决方案。这就是am assoc数组的调试输出所需要的。
dixus

33

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

目标:要获得一行1,000项的内容,格式为:“键:值,键2:值2”

我们有数组(例如):

$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_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


4
$s = ''; foreach ($array as $k=>$v) { if ($s !== null) { $s .= ','; } $s .= "{$k}:{$v}"; }胜过其他所有。
Fleshgrinder

1
http_build_query工作台缺少urldecode以便与其他URL进行比较。
尼克

另一种选择:substr(str_replace('"', '', json_encode($headers)), 1, -1);
nickl-

1
注意:如果其中有空格,它将更改您的值。在http_build_query用加号(替换空格+)字符。
Erfun

9

我会用serialize()json_encode()

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


3

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

爱迪生


1
我喜欢array_walk方法,但是我不明白为什么人们建议使用create_function而不是仅使用匿名函数?
Rikki 2014年

@Rikki兼容性!
Shiplu Mokaddim 2014年

啊! 我没有意识到这是PHP4!
Rikki 2014年

@Rikki 没有。它是PHP 5.3之前的版本。匿名函数首次出现在PHP 5.3上
Shiplu Mokaddim,2014年

但是它是在PHP 4.0.1中引入的,PHP4也是如此。语义...在次要版本更新中添加与匿名功能同样重要的功能很奇怪。
Rikki 2014年

2

更改

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

如果要保留整个String而没有最后一个$ 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循环的有效替代方法。已更新;)
托尼·吉尔

2

用于调试目的。递归将嵌套数组的数组写入字符串。用于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";
}

2

您也可以使用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");

1

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

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

1

还有用于打印调试输出的更常见的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)

0

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

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

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.