Come implodere array con chiave e valore senza foreach in PHP


112

Senza foreach , come posso trasformare un array come questo

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

a una stringa come questa

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

Ci ho implode()già pensato , ma non fa implodere la chiave con esso.

Se foreach è necessario, è possibile non annidare foreach?

EDIT: ho cambiato la stringa


EDIT2 / UPDATE: questa domanda è stata posta molto tempo fa. A quel tempo, volevo scrivere tutto in una riga, quindi avrei usato operatori ternari e annidato chiamate di funzione incorporate a favore di foreach. Non era una buona pratica! Scrivi codice che sia leggibile, che sia conciso o meno, non importa molto.

In questo caso: mettere il foreach in una funzione sarà molto più leggibile e modulare che scrivere un one-liner (anche se tutte le risposte sono ottime!).


Quanto sarebbe nidificato foreach?
Shubham

Cosa stai tentando? Perché hai questi vincoli?
Madara's Ghost

questa era la mia classe di database per l'app Web che sto costruendo, non voglio che sembri disordinato poiché è già popolato con un mucchio di foreach e for-loop tutti insieme
tom91136

1
Questa risposta selezionata è il metodo che hai richiesto, tuttavia va notato che è criticamente più lento e che se stai archiviando queste informazioni tramite un database sarebbe di gran lunga superiore sia a un ciclo che a questo usare solo json_encode. Allegato A: willem.stuursma.name/2010/11/22/…
Caso

Risposte:


187

e un altro modo:

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

o:

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

6
Questo metodo è ciò che l'autore stava chiedendo, ma va notato che è criticamente più lento e che se si memorizzano queste informazioni tramite un database sarebbe di gran lunga superiore sia a un ciclo che a questo usare solo json_encode. Allegato A: willem.stuursma.name/2010/11/22/…
Caso

Nessuno dei collegamenti qui sembra funzionare più, echo "Hello, World!";dovrei vedere esempi di codice di queste funzioni?
Félix Gagnon-Grenier

Questo metodo è molto facile da personalizzare in base alle proprie esigenze.
Kabir Hossain

Stavo usando questo metodo per creare opzioni di selezione e popolare l'opzione selezionata, e poiché entrambi gli array devono avere le stesse dimensioni, puoi fare qualcosa di simile per il secondo array. array_fill(0, $input, 'selected-value-you want-to-check-against');Questo genererà la stessa matrice di dimensioni con un valore singolo per tutte le righe.
krasenslavov

188

Puoi usare http_build_query , in questo modo:

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

Produzione:

item1=object1, item2=object2 

dimostrazione


6
Non ho mai utilizzato gli altri parametri di http_build_query.
Shiplu Mokaddim

16
+1 Diavolo sì, adoro trovare piccole pepite di bontà come questa :)
Ben

8
Attenzione alla codifica della stringa! Se non stai costruendo un URL forse non lo vuoi sul tuo array key & value
Matteo

8
@Matteo Puoi avvolgere http_build_queryin urldecodeper evitarlo.
Afterlame

3
Soluzione geniale. Era tutto ciò di cui avevo bisogno per un output di debug di am assoc array.
dixus

33

Ho speso misurazioni (100000 iterazioni), quale modo più veloce per incollare un array associativo?

Obiettivo: ottenere una riga di 1.000 elementi, in questo formato: "chiave: valore, chiave2: valore2"

Abbiamo array (ad esempio):

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

Test numero uno:

Usa http_build_query e str_replace :

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

Tempo medio per implodere 1000 elementi: 0.00012930955084904

Test numero due:

Usa array_map e implode :

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

Tempo medio per implodere 1000 elementi: 0.0004890081976675

Test numero tre:

Usa array_walk e implode :

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

Tempo medio per implodere 1000 elementi: 0.0003874126245348

Test numero quattro:

Usa foreach :

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

Tempo medio per implodere 1000 elementi: 0.00026632803902445

Posso concludere che il modo migliore per incollare l'array - usa http_build_query e str_replace


4
$s = ''; foreach ($array as $k=>$v) { if ($s !== null) { $s .= ','; } $s .= "{$k}:{$v}"; }supera tutti gli altri.
Fleshgrinder,

1
Al banco http_build_query manca il codice urldecode per essere comparativo agli altri.
nickl-

Un'altra opzione:substr(str_replace('"', '', json_encode($headers)), 1, -1);
nickl-

1
ATTENZIONE: modifica i valori se contiene spazio. La http_build_querysostituisce gli spazi con più ( +carattere).
Erfun

9

Userei serialize()o json_encode().

Anche se non ti darà la stringa esatta del risultato che desideri, sarebbe molto più facile codificare / memorizzare / recuperare / decodificare in seguito.


3

Utilizzando 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
Mi piace l'approccio array_walk, ma non capisco perché le persone suggeriscano di utilizzare create_functioninvece di utilizzare solo una funzione anonima?
Rikki

@Rikki Compatibility!
Shiplu Mokaddim

Ah! Non mi rendevo conto che fosse una cosa PHP4!
Rikki

@Rikki No . È pre PHP 5.3 cosa. La funzione anonima è apparsa per la prima volta su PHP 5.3
Shiplu Mokaddim

Ma è stato introdotto in PHP 4.0.1, quindi è una cosa PHP4. Semantica ... Aggiungere una funzionalità significativa come le funzioni anonime in un aggiornamento di una versione minore è bizzarro.
Rikki

2

Modificare

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

se vuoi resuscitare l'intera stringa senza l'ultima $ glue

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

E l'utilizzo:

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

Capisco che questa sia una valida alternativa alla scrittura ogni volta di un ciclo foreach. UPVOTED;)
tony gil

2

Per scopi di debug. Ricorsivo scrive un array di array annidati in una stringa. Usato foreach. La funzione memorizza i caratteri della lingua nazionale.

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

Potresti usare anche array_reduce di PHP ,

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

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

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

1

Per creare mysql dove le condizioni da 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

Esistono anche var_export e print_r più comunemente noti per la stampa dell'output di debug, ma entrambe le funzioni possono richiedere un argomento opzionale per restituire una stringa.

Utilizzando l'esempio della domanda come dati.

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

Usando print_rper trasformare l'array in una stringa

Questo produrrà una rappresentazione leggibile dall'uomo della variabile.

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

Produrrà:

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

Usando var_exportper trasformare l'array in una stringa

Che produrrà una rappresentazione di stringa php della variabile.

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

Produrrà:

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

Poiché è php valido, possiamo valutarlo.

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

Uscite:

bool(true)

0

Ecco un semplice esempio, usando 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;
    }

}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.