Comment imploser un tableau avec une clé et une valeur sans foreach en PHP

112

Sans foreach , comment puis-je transformer un tableau comme celui-ci

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

à une chaîne comme celle-ci

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

J'y ai implode()déjà pensé , mais cela n'implose pas la clé avec.

Si foreach c'est nécessaire, est-il possible de ne pas nicher le foreach?

EDIT: j'ai changé la chaîne


EDIT2 / UPDATE: Cette question a été posée il y a assez longtemps. À ce moment-là, je voulais tout écrire sur une seule ligne afin d'utiliser des opérateurs ternaires et d'imbriquer des appels de fonction intégrés en faveur de foreach. Ce n'était pas une bonne pratique! Écrire un code lisible, qu'il soit concis ou non, n'a pas beaucoup d'importance.

Dans ce cas: mettre le foreach dans une fonction sera beaucoup plus lisible et modulaire que d'écrire un one-liner (même si toutes les réponses sont excellentes!).

tom91136
la source
À quel point foreach serait-il nécessaire?
Shubham du
Que tentez-vous? Pourquoi avez-vous ces contraintes?
Madara's Ghost
c'était ma classe de base de données pour l'application Web que je construis, je ne veux pas qu'elle ait l'air désordonnée car elle est déjà remplie d'un tas de foreach et for-loop tous ensemble
tom91136
1
Cette réponse sélectionnée est la méthode que vous avez demandée, mais il convient de noter qu'elle est considérablement plus lente et que si vous stockez ces informations via une base de données, elle serait largement supérieure à la fois à une boucle et à ceci d'utiliser simplement json_encode. Pièce A: willem.stuursma.name/2010/11/22/…
Affaire
1
duplication possible du moyen le plus rapide d'imploser un tableau associatif avec des clés
Félix Gagnon-Grenier

Réponses:

187

et d'une autre manière:

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

ou:

$output = implode(', ', array_map(
    function ($v, $k) { return sprintf("%s='%s'", $k, $v); },
    $input,
    array_keys($input)
));
robsch
la source
6
Cette méthode est ce que l'auteur demandait, mais il convient de noter qu'elle est considérablement plus lente et que si vous stockez ces informations via une base de données, elle serait largement supérieure à la fois à une boucle et à ceci d'utiliser simplement json_encode. Pièce A: willem.stuursma.name/2010/11/22/…
Cas
Aucun des liens ici ne semble plus fonctionner, ils tous echo "Hello, World!";Dois-je voir des exemples de code de ces fonctions?
Félix Gagnon-Grenier
Cette méthode est très facile à personnaliser en fonction de sa propre demande.
Kabir Hossain
J'utilisais cette méthode pour créer des options de sélection et remplir l'option sélectionnée, et comme les deux tableaux doivent être de la même taille, vous pouvez faire quelque chose comme ça pour le deuxième tableau. array_fill(0, $input, 'selected-value-you want-to-check-against');Cela générera un tableau de même taille avec une valeur unique pour toutes les lignes.
krasenslavov
188

Vous pouvez utiliser http_build_query , comme ceci:

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

Production:

item1=object1, item2=object2 

Démo

ragoût
la source
6
Jamais utilisé les autres paramètres de http_build_query.
Shiplu Mokaddim du
16
+1 Enfer ouais j'adore trouver de petites pépites de bonté comme ça :)
Ben
8
Méfiez-vous de l'encodage de la chaîne! Si vous ne construisez pas une URL, peut-être que vous ne le voulez pas sur votre clé et valeur de tableau
Matteo
8
@Matteo Vous pouvez envelopper http_build_querydans urldecodede l' éviter.
Afterlame
3
Solution Genius. C'était tout ce dont j'avais besoin pour une sortie de débogage d'un tableau assoc.
dixus
33

J'ai passé des mesures (100000 itérations), quel moyen le plus rapide pour coller un tableau associatif?

Objectif: obtenir une ligne de 1 000 éléments, au format suivant: "clé: valeur, clé2: valeur2"

Nous avons un tableau (par exemple):

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

Test numéro un:

Utilisez http_build_query et str_replace :

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

Temps moyen pour imploser 1000 éléments: 0,00012930955084904

Test numéro deux:

Utilisez array_map et imploser :

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

Temps moyen pour imploser 1000 éléments: 0,0004890081976675

Test numéro trois:

Utilisez array_walk et imploser :

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

Temps moyen pour imploser 1000 éléments: 0,0003874126245348

Test numéro quatre:

Utilisez foreach :

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

Temps moyen pour imploser 1000 éléments: 0,00026632803902445

Je peux conclure que la meilleure façon de coller le tableau - utilisez http_build_query et str_replace

Maxim Tkach
la source
4
$s = ''; foreach ($array as $k=>$v) { if ($s !== null) { $s .= ','; } $s .= "{$k}:{$v}"; }surpasse tous les autres.
Fleshgrinder du
1
Le banc http_build_query n'a pas de code urldecode pour être comparé aux autres.
nickl-
Autre option:substr(str_replace('"', '', json_encode($headers)), 1, -1);
nickl-
1
ATTENTION: cela modifie vos valeurs s'il y a de l'espace. Le http_build_queryremplace les espaces par le caractère plus ( +).
Erfun le
9

J'utiliserais serialize()ou json_encode().

Bien que cela ne donne pas la chaîne de résultat exacte que vous souhaitez, il serait beaucoup plus facile d'encoder / stocker / récupérer / décoder plus tard.

Fantôme de Madara
la source
3

Utilisation de 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);

IDÉONE

Shiplu Mokaddim
la source
1
J'aime l'approche array_walk, mais je ne comprends pas pourquoi les gens suggèrent d'utiliser create_functionau lieu d'utiliser simplement une fonction anonyme?
Rikki
Compatibilité @Rikki!
Shiplu Mokaddim
Ah! Je n'avais pas réalisé que c'était une chose PHP4!
Rikki
@Rikki Non . C'est quelque chose d'avant PHP 5.3. La fonction anonyme est apparue pour la première fois sur PHP 5.3
Shiplu Mokaddim
Mais il a été introduit dans PHP 4.0.1, il en va de même pour PHP4. Sémantique ... Ajouter une fonctionnalité aussi importante que des fonctions anonymes dans une mise à jour de version mineure est bizarre.
Rikki
2

Changement

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

si vous souhaitez réécrire la chaîne entière sans le dernier $ glue

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

Et l'utilisation:

$str = key_implode($yourArray, ",");
Björn
la source
Je comprends que c'est une alternative valable à l'écriture d'une boucle foreach à chaque fois. UPVOTED;)
tony gil
2

À des fins de débogage. Récursif écrit un tableau de tableaux imbriqués dans une chaîne. Utilisé pourchaque. La fonction stocke les caractères de la langue nationale.

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";
}
Sergey Yurich
la source
2

Vous pouvez également utiliser array_reduce de PHP ,

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

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

$imploded = array_reduce(array_keys($a), "acc");
Sapenov
la source
1

Pour créer mysql où les conditions du tableau

$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'))
Ajay Patidar
la source
1

Il existe également var_export et print_r plus connus pour imprimer la sortie de débogage, mais les deux fonctions peuvent prendre un argument facultatif pour renvoyer une chaîne à la place.

En utilisant l'exemple de la question comme données.

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

Utilisation print_rpour transformer le tableau en une chaîne

Cela produira une représentation lisible par l'homme de la variable.

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

Sortira:

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

Utilisation var_exportpour transformer le tableau en une chaîne

Ce qui produira une représentation sous forme de chaîne php de la variable.

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

Sortira:

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

Parce que c'est du php valide, nous pouvons l'évaluer.

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

Les sorties:

bool(true)
nickl-
la source
0

Voici un exemple simple, utilisant la classe:

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

}
Ivan Ferrer
la source