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: この質問はかなり前に尋ねられました。当時、私はすべてを1行で記述したかったため、3項演算子とネストされた組み込み関数呼び出しを使用してforeachを優先しました。それは良い習慣ではありませんでした!簡潔であるかどうかにかかわらず、読みやすいコードを書くことはそれほど重要ではありません。

この場合、関数にforeachを入れる方が、ワンライナーを書くよりもはるかに読みやすくモジュール化されます(すべての答えは素晴らしいですが!)。


どのようにネストされたforeachが必要になるでしょうか?
Shubham

何をしようとしているの?なぜこれらの制約があるのですか?
マダラのゴースト

これは、それがすでにすべて一緒のforeachの束とし、forループ読み込まれますので、私はそれが散らかっを見たくない、私は建物だWebアプリケーションのための私のデータベースクラスだった
tom91136

1
この選択された答えはあなたが求めた方法ですが、非常に遅く、データベースを介してこの情報を保存している場合は、ループとjson_encodeを使用するだけの両方よりもはるかに優れていることに注意してください。別紙A:willem.stuursma.name/2010/11/22/...
ケース

回答:


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を使用するだけの両方よりもはるかに優れていることに注意してください。別紙A:willem.stuursma.name/2010/11/22/...
ケース

ここのリンクはどれも機能していないようです。それらはすべてecho "Hello, World!";これらの関数のコード例を表示する必要がありますか?
フェリックス・ガニオン-グルニエ

この方法は、自分の要求に応じて非常に簡単にカスタマイズできます。
Kabir Hossain 2016年

私はこの方法を使用して選択オプションを作成し、選択したオプションを設定しました。両方の配列は同じサイズでなければならないので、2番目の配列に対してこのようなことを行うことができます。array_fill(0, $input, 'selected-value-you want-to-check-against');これにより、すべての行に対して単一の値を持つ同じサイズの配列が生成されます。
Krasenslavov

187

次のように、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 2012

16
+1地獄そう私はこのような善の小さなナゲットを見つけるのが大好きです:)
Ben

8
文字列エンコーディングに注意してください!URLを作成していない場合、配列のキーと値にURLを使用したくないかもしれません
Matteo

8
@Matteoあなたはそれを避けるためにラップhttp_build_queryすることができurldecodeます。
Afterlame 2014年

3
天才ソリューション。assoc配列のデバッグ出力に必要なのはそれだけでした。
ディクサス2015

33

私は測定(100000回の反復)を費やしましたが、連想配列を接着する最も速い方法は何ですか?

目的: 1,000個のアイテムの行を、次の形式で取得します: "key:value、key2:value2"

配列があります(例):

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

テスト番号1:

http_build_querystr_replaceを使用します

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

1000個の要素を爆破する平均時間:0.00012930955084904

テスト番号2:

array_mapimplodeを使用します。

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

1000個の要素を爆破する平均時間:0.0004890081976675

テスト番号3:

array_walkimplodeを使用します。

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

1000個の要素を爆破する平均時間:0.0003874126245348

テスト番号4:

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 2017年

1
http_build_queryベンチには、他と比較するためのurldecodeがありません。
nickl-

別のオプション: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);

IDEONE


1
私はarray_walkアプローチが好きですがcreate_function、匿名関数を使用するだけでなく、なぜ使用を提案するのか理解できません。
リッキ

@Rikkiの互換性!
Shiplu Mokaddim、2014

ああ!私はそれがPHP4のものであることを知らなかった!
Rikki 2014年

@Rikki はありません。PHP 5.3より前のもの。無名関数はPHP 5.3で最初に登場
Shiplu Mokaddim

しかし、それはPHP 4.0.1で導入されたので、PHP4のものです。セマンティクス...マイナーバージョンアップデートで匿名機能と同じくらい重要な機能を追加するのは奇妙です。
リッキ

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ループを作成する有効な代替手段であることを理解しています。UPVOTED;)
トニー・ギル

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

}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.