Jak implodować tablicę z kluczem i wartością bez foreach w PHP


112

Bez foreach , jak mogę zmienić taką tablicę

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

do takiego ciągu

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

Już o tym myślałem implode(), ale nie powoduje implozji klucza.

Jeśli za każdym razem jest to konieczne, czy można nie zagnieżdżać wszystkich?

EDYCJA: Zmieniłem ciąg


EDIT2 / UPDATE: To pytanie zostało zadane dość dawno temu. W tamtym czasie chciałem napisać wszystko w jednej linii, więc użyłem operatorów trójskładnikowych i zagnieżdżonych wywołań funkcji na korzyść foreach. To nie była dobra praktyka! Pisanie kodu, który jest czytelny, czy jest zwięzły, czy nie, nie ma większego znaczenia.

W tym przypadku: umieszczenie foreach w funkcji będzie dużo bardziej czytelne i modularne niż pisanie tekstu w jednej linijce (chociaż wszystkie odpowiedzi są świetne!).


Jak zagnieżdżone byłoby konieczne?
— Shubham,

Czego próbujesz? Dlaczego masz te ograniczenia?
— Madara's Ghost

to była moja klasa bazy danych dla aplikacji internetowej, którą tworzę, nie chcę, aby wyglądała niechlujnie, ponieważ jest już wypełniona
— wieloma pętlami

1
Ta wybrana odpowiedź to metoda, o którą prosiłeś, jednak należy zauważyć, że jest ona znacznie wolniejsza i że jeśli przechowujesz te informacje w bazie danych, byłoby znacznie lepsze zarówno od pętli, jak i po prostu użyć json_encode. Załącznik A: willem.stuursma.name/2010/11/22/...
— Sprawa,

Odpowiedzi:


187

i w inny sposób:

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

lub:

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

6
Ta metoda jest tym, o co prosił autor, ale należy zauważyć, że jest ona znacznie wolniejsza i że jeśli przechowujesz te informacje w bazie danych, byłoby znacznie lepsze zarówno od pętli, jak i po prostu użyć json_encode. Załącznik A: willem.stuursma.name/2010/11/22/…
— Sprawa,

Żaden z linków tutaj nie wydaje się już działać, wszystkie echo "Hello, World!";Czy mam zobaczyć przykłady kodu tych funkcji?
— Félix Gagnon-Grenier

Ta metoda jest bardzo łatwa do dostosowania zgodnie z własnym zapotrzebowaniem.
— Kabir Hossain

Używałem tej metody do budowania opcji zaznaczania i wypełniania wybranej opcji, a ponieważ obie tablice muszą mieć ten sam rozmiar, możesz zrobić coś takiego dla drugiej tablicy. array_fill(0, $input, 'selected-value-you want-to-check-against');Spowoduje to wygenerowanie tablicy tego samego rozmiaru z jedną wartością dla wszystkich wierszy.
— krasenslavov

188

Możesz użyć http_build_query , na przykład:

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

Wynik:

item1=object1, item2=object2 

Próbny


6
Nigdy nie korzystałem z innych parametrów http_build_query.
— Shiplu Mokaddim,

16
+1 do diabła, tak, uwielbiam znajdować takie małe bryłki dobra :)
— Ben

8
Uważaj na kodowanie ciągów! Jeśli nie tworzysz adresu URL, być może nie chcesz go w swoim kluczu i wartości tablicy
— Matteo

8
@Matteo Można owinąć http_build_queryw urldecodecelu uniknięcia go.
— Afterlame

3
Genialne rozwiązanie. To było wszystko, czego potrzebowałem do debugowania danych wyjściowych z tablicy am assoc.
— dixus

33

Wydałem pomiary (100000 iteracji), jaki jest najszybszy sposób na przyklejenie tablicy asocjacyjnej?

Cel: uzyskanie wiersza zawierającego 1000 pozycji w następującym formacie: „klucz: wartość, klucz2: wartość2”

Mamy tablicę (na przykład):

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

Test numer jeden:

Użyj http_build_query i str_replace :

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

Średni czas implodowania 1000 elementów: 0,00012930955084904

Test numer dwa:

Użyj array_map i implode :

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

Średni czas implodowania 1000 elementów: 0,0004890081976675

Test numer trzy:

Użyj array_walk i implode :

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

Średni czas implodowania 1000 elementów: 0,0003874126245348

Test numer cztery:

Użyj dla każdego :

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

Średni czas implodowania 1000 elementów: 0,00026632803902445

Mogę stwierdzić, że najlepszym sposobem na przyklejenie tablicy - użyj http_build_query i str_replace


4
$s = ''; foreach ($array as $k=>$v) { if ($s !== null) { $s .= ','; } $s .= "{$k}:{$v}"; }przewyższa wszystkie inne.
— Fleshgrinder

1
W stanowisku http_build_query brakuje kodu urldkodu, aby można go było porównać z innymi.
— nickl-

Inna opcja:substr(str_replace('"', '', json_encode($headers)), 1, -1);
— nickl-

1
UWAGA: Zmienia wartości, jeśli jest w nim miejsce. http_build_queryZastępuje spacje z plus ( +) charakter.
— Erfun

9

Użyłbym serialize()lub json_encode().

Chociaż nie da to dokładnego ciągu wynikowego, który chcesz, byłoby znacznie łatwiej zakodować / zapisać / pobrać / zdekodować później.


3

Korzystanie z 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
Podoba mi się podejście array_walk, ale nie rozumiem, dlaczego ludzie sugerują używanie create_functionzamiast zwykłej funkcji anonimowej?
— Rikki

@Rikki Compatibility!
— Shiplu Mokaddim

Ach! Nie zdawałem sobie sprawy, że to kwestia PHP4!
— Rikki

@Rikki nr . Jego rzecz sprzed PHP 5.3. Funkcja anonimowa pojawiła się po raz pierwszy w PHP 5.3
— Shiplu Mokaddim

Ale został wprowadzony w PHP 4.0.1, więc jest rzeczą PHP4. Semantyka ... Dodanie funkcji tak ważnej jak funkcje anonimowe w pomniejszej aktualizacji wersji jest dziwaczne.
— Rikki

2

Zmiana

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

jeśli chcesz przywrócić cały String bez ostatniego kleju $

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

I użycie:

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

Rozumiem, że jest to dobra alternatywa dla pisania pętli foreach za każdym razem. ZGŁOSOWANO;)
— tony gil

2

Do celów debugowania. Rekursywnie zapisuje tablicę zagnieżdżonych tablic do ciągu. Używane foreach. Funkcja przechowuje znaki języka narodowego.

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

Możesz również użyć funkcji array_reduce w PHP ,

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

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

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

1

Do tworzenia mysql, gdzie warunki z tablicy

$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

Istnieją również opcje var_export i print_r, które są bardziej znane z drukowania wyników debugowania, ale obie funkcje mogą przyjmować opcjonalny argument, aby zamiast tego zwrócić ciąg.

Na podstawie przykładu z pytania jako danych.

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

Używanie print_rdo przekształcenia tablicy w ciąg

Spowoduje to wyświetlenie czytelnej dla człowieka reprezentacji zmiennej.

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

Wyświetli:

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

Używanie var_exportdo przekształcenia tablicy w ciąg

Który wyświetli reprezentację zmiennej w postaci ciągu php.

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

Wyświetli:

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

Ponieważ jest to poprawny php, możemy go ocenić.

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

Wyjścia:

bool(true)

0

Oto prosty przykład, używając 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;
    }

}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.