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.