So implodieren Sie ein Array mit Schlüssel und Wert ohne foreach in PHP


111

Wie kann ich ohne foreach ein Array wie dieses drehen?

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

zu einem String wie diesem

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

Ich habe implode()bereits darüber nachgedacht , aber es implodiert den Schlüssel nicht damit.

Ist es möglich, den foreach nicht zu verschachteln, wenn dies erforderlich ist?

EDIT: Ich habe die Zeichenfolge geändert


EDIT2 / UPDATE: Diese Frage wurde vor einiger Zeit gestellt. Zu dieser Zeit wollte ich alles in eine Zeile schreiben, um ternäre Operatoren und eingebettete Funktionsaufrufe zugunsten von foreach zu verwenden. Das war keine gute Praxis! Schreiben Sie lesbaren Code, egal ob er präzise ist oder nicht.

In diesem Fall: Das Einfügen des foreach in eine Funktion ist viel lesbarer und modularer als das Schreiben eines Einzeilers (obwohl alle Antworten großartig sind!).


Wie verschachtelt wäre jede Notwendigkeit?
Shubham

Was versuchst du? Warum haben Sie diese Einschränkungen?
Madaras Geist

Dies war meine Datenbankklasse für die Web-App, die ich gerade erstelle. Ich möchte nicht, dass sie unordentlich aussieht, da sie bereits mit einer Reihe von Foreach- und For-Loops
gefüllt ist

1
Diese ausgewählte Antwort ist eine Methode, nach der Sie gefragt haben. Es ist jedoch zu beachten, dass sie kritisch langsamer ist und dass das Speichern dieser Informationen über eine Datenbank sowohl einer Schleife als auch der Verwendung von json_encode weit überlegen wäre. Anlage
Fall

Antworten:


187

und ein anderer Weg:

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

oder:

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

6
Diese Methode wurde vom Autor gefordert, es sollte jedoch beachtet werden, dass sie kritisch langsamer ist und dass das Speichern dieser Informationen über eine Datenbank sowohl einer Schleife als auch der Verwendung von json_encode weit überlegen wäre. Anlage
Fall

Keiner der Links hier scheint mehr zu funktionieren, alle. echo "Hello, World!";Sollte ich Codebeispiele für diese Funktionen sehen?
Félix Gagnon-Grenier

Diese Methode lässt sich sehr einfach an die eigenen Anforderungen anpassen.
Kabir Hossain

Ich habe diese Methode verwendet, um Auswahloptionen zu erstellen und die ausgewählte Option zu füllen. Da beide Arrays dieselbe Größe haben müssen, können Sie für das zweite Array so etwas tun. array_fill(0, $input, 'selected-value-you want-to-check-against');Dadurch wird ein Array gleicher Größe mit einem einzigen Wert für alle Zeilen generiert.
Krasenslawow

185

Sie könnten http_build_query wie folgt verwenden :

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

Ausgabe:

item1=object1, item2=object2 

Demo


5
Nie die anderen Parameter von verwendet http_build_query.
Shiplu Mokaddim

16
+1 Hölle ja, ich liebe es, kleine Nuggets von Güte wie diese zu finden :)
Ben

8
Hüten Sie sich vor der Zeichenfolgencodierung! Wenn Sie keine URL erstellen, möchten Sie diese möglicherweise nicht auf Ihrem Array-Schlüssel und -Wert haben
Matteo

8
@Matteo Sie wickeln kann http_build_queryin urldecodesie zu vermeiden.
Afterlame

3
Geniale Lösung. Das war alles, was ich für eine Debug-Ausgabe von am assoc array brauchte.
Dixus

33

Ich habe Messungen (100000 Iterationen) durchgeführt. Wie kann ich ein assoziatives Array am schnellsten zusammenkleben?

Ziel: Um eine Zeile mit 1.000 Elementen in diesem Format zu erhalten: "Schlüssel: Wert, Schlüssel2: Wert2"

Wir haben Array (zum Beispiel):

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

Test Nummer eins:

Verwenden Sie http_build_query und str_replace :

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

Durchschnittliche Zeit zum Implodieren von 1000 Elementen: 0,00012930955084904

Test Nummer zwei:

Verwenden Sie array_map und implodieren Sie :

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

Durchschnittliche Zeit zum Implodieren von 1000 Elementen: 0,0004890081976675

Test Nummer drei:

Verwenden Sie array_walk und implodieren Sie :

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

Durchschnittliche Zeit zum Implodieren von 1000 Elementen: 0,0003874126245348

Test Nummer vier:

Verwenden Sie foreach :

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

Durchschnittliche Zeit zum Implodieren von 1000 Elementen: 0,00026632803902445

Ich kann daraus schließen, dass der beste Weg, um das Array zu kleben - verwenden Sie http_build_query und str_replace


4
$s = ''; foreach ($array as $k=>$v) { if ($s !== null) { $s .= ','; } $s .= "{$k}:{$v}"; }übertrifft alle anderen.
Fleischwolf

1
Der http_build_query-Bank fehlt der URL-Code, um mit den anderen vergleichbar zu sein.
Nickl

Eine andere Option:substr(str_replace('"', '', json_encode($headers)), 1, -1);
Nickl

1
VORSICHT: Es ändert Ihre Werte, wenn Platz darin ist. Das http_build_queryersetzt Leerzeichen durch Pluszeichen ( +).
Erfun

9

Ich würde serialize()oder verwenden json_encode().

Es gibt zwar nicht genau die gewünschte Ergebniszeichenfolge, aber es wäre viel einfacher, sie später zu codieren / speichern / abrufen / dekodieren.


3

Mit 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
Ich mag den array_walk-Ansatz, aber ich verstehe nicht, warum Leute vorschlagen, create_functionanstatt nur eine anonyme Funktion zu verwenden?
Rikki

@ Rikki Kompatibilität!
Shiplu Mokaddim

Ah! Ich wusste nicht, dass es eine PHP4-Sache ist!
Rikki

@ Rikki Nr . Es ist vor PHP 5.3 Sache. Anonyme Funktion erschien zuerst auf PHP 5.3
Shiplu Mokaddim

Aber es wurde in PHP 4.0.1 eingeführt, also ist es eine PHP4-Sache. Semantik ... Das Hinzufügen einer Funktion, die so wichtig ist wie anonyme Funktionen in einem kleineren Versionsupdate, ist bizarr.
Rikki

2

Veränderung

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

Wenn Sie den gesamten String ohne den letzten $ Kleber erneut speichern möchten

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

Und die Verwendung:

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

Ich verstehe, dass dies eine gültige Alternative zum Schreiben einer foreach-Schleife jedes Mal ist. UPVOTED;)
Tony Gil

2

Zum Debuggen. Rekursiv Schreiben Sie ein Array verschachtelter Arrays in eine Zeichenfolge. Für jeden verwendet. Die Funktion speichert Zeichen in der Landessprache.

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

Sie können auch Array_reduce von PHP verwenden .

$a = ['Name' => 'Last Name'];

function acc($acc,$k)use($a){ return $acc .= $k.":".$a[$k].",";}

$imploded = array_reduce(array_keys($a), "acc");

1

Zum Erstellen von MySQL, wo Bedingungen aus Array

$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

Es gibt auch var_export und print_r , die allgemeiner zum Drucken von Debug-Ausgaben bekannt sind, aber beide Funktionen können ein optionales Argument verwenden, um stattdessen eine Zeichenfolge zurückzugeben.

Verwenden Sie das Beispiel aus der Frage als Daten.

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

Verwenden Sie print_r, um das Array in eine Zeichenfolge umzuwandeln

Dies gibt eine lesbare Darstellung der Variablen aus.

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

Wird ausgegeben:

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

Verwenden Sie var_export, um das Array in eine Zeichenfolge umzuwandeln

Womit eine PHP-String-Darstellung der Variablen ausgegeben wird.

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

Wird ausgegeben:

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

Da es gültiges PHP ist, können wir es bewerten.

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

Ausgänge:

bool(true)

0

Hier ist ein einfaches Beispiel mit class:

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

}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.