Bagaimana mengimplementasikan array dengan key dan value tanpa foreach di PHP

112

Tanpa sebelumnya , bagaimana saya bisa mengubah array seperti ini

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

ke string seperti ini

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

Saya sudah memikirkannya implode(), tetapi tidak meledak kunci dengan itu.

Jika foreach itu perlu, mungkinkah untuk tidak menyusun foreach?

EDIT: Saya telah mengubah string


EDIT2 / UPDATE: Pertanyaan ini ditanyakan beberapa waktu yang lalu. Pada saat itu, saya ingin menulis semuanya dalam satu baris jadi saya akan menggunakan operator terner dan panggilan fungsi bawaan nest untuk mendukung foreach. Itu bukan praktik yang baik! Menulis kode yang mudah dibaca, ringkas atau tidak, tidak terlalu penting.

Dalam hal ini: menempatkan foreach dalam suatu fungsi akan jauh lebih mudah dibaca dan modular daripada menulis satu baris (Meskipun semua jawabannya bagus!).

tom91136
sumber
Seberapa jauh dibutuhkan?
Shubham
Apa yang kamu coba? Mengapa Anda memiliki kendala tersebut?
Hantu Madara
ini adalah kelas database saya untuk aplikasi web yang saya bangun, saya tidak ingin terlihat berantakan karena sudah diisi dengan banyak foreach dan for-loop bersama
tom91136
1
Jawaban yang dipilih ini adalah metode yang Anda minta, namun perlu dicatat bahwa ini sangat lambat dan jika Anda menyimpan informasi ini melalui database, itu akan jauh lebih baik daripada loop dan ini hanya menggunakan json_encode. Bukti A: willem.stuursma.name/2010/11/22/…
Kasus
1
kemungkinan duplikat cara tercepat untuk meledakkan array asosiatif dengan kunci
Félix Gagnon-Grenier

Jawaban:

187

dan cara lain:

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

atau:

$output = implode(', ', array_map(
    function ($v, $k) { return sprintf("%s='%s'", $k, $v); },
    $input,
    array_keys($input)
));
robsch
sumber
6
Metode ini adalah yang diminta oleh Penulis, tetapi perlu dicatat bahwa ini sangat lambat dan jika Anda menyimpan informasi ini melalui database, metode ini akan jauh lebih unggul daripada loop dan ini hanya menggunakan json_encode. Bukti A: willem.stuursma.name/2010/11/22/…
Kasus
Tidak ada tautan di sini yang tampaknya berfungsi lagi, semuanya echo "Hello, World!";Haruskah saya melihat contoh kode dari fungsi-fungsi itu?
Félix Gagnon-Grenier
Cara ini sangat mudah untuk di sesuaikan sesuai permintaan sendiri.
Kabir Hossain
Saya menggunakan metode ini untuk membangun opsi terpilih dan mengisi opsi yang dipilih, dan karena kedua larik harus berukuran sama, Anda dapat melakukan sesuatu seperti ini untuk larik kedua. array_fill(0, $input, 'selected-value-you want-to-check-against');Ini akan menghasilkan larik ukuran yang sama dengan nilai tunggal untuk semua baris.
krasenslavov
188

Anda bisa menggunakan http_build_query , seperti ini:

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

Keluaran:

item1=object1, item2=object2 

Demo

stewe
sumber
6
Jangan pernah menggunakan parameter lain dari http_build_query.
Shiplu Mokaddim
16
+1 Sial, ya, saya suka menemukan potongan kecil kebaikan seperti ini :)
Ben
8
Waspadalah terhadap pengkodean string! Jika Anda tidak membuat URL mungkin Anda tidak menginginkannya di kunci & nilai array Anda
Matteo
8
@Matteo Anda dapat membungkus http_build_querydi urldecodeuntuk menghindarinya.
Afterlame
3
Solusi jenius. Hanya itu yang saya butuhkan untuk keluaran debug dari array am assoc.
dixus
33

Saya menghabiskan pengukuran (100000 iterasi), cara tercepat apa untuk merekatkan array asosiatif?

Tujuan: Untuk mendapatkan baris yang terdiri dari 1.000 item, dalam format ini: "key: value, key2: value2"

Kami memiliki array (misalnya):

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

Tes nomor satu:

Gunakan http_build_query dan str_replace :

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

Rata-rata waktu untuk meledakkan 1000 elemen: 0,00012930955084904

Tes nomor dua:

Gunakan array_map dan implode :

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

Rata-rata waktu untuk meledakkan 1000 elemen: 0,0004890081976675

Tes nomor tiga:

Gunakan array_walk dan implode :

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

Rata-rata waktu untuk meledakkan 1000 elemen: 0,0003874126245348

Tes nomor empat:

Gunakan foreach :

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

Rata-rata waktu untuk meledakkan 1000 elemen: 0,00026632803902445

Saya dapat menyimpulkan bahwa cara terbaik untuk merekatkan array - gunakan http_build_query dan str_replace

Maxim Tkach
sumber
4
$s = ''; foreach ($array as $k=>$v) { if ($s !== null) { $s .= ','; } $s .= "{$k}:{$v}"; }mengungguli yang lain.
Fleshgrinder
1
Bangku http_build_query tidak memiliki urldecode agar dapat dibandingkan dengan yang lain.
nickl-
Opsi lain:substr(str_replace('"', '', json_encode($headers)), 1, -1);
nickl-
1
PERHATIAN: Ini mengubah nilai Anda jika ada spasi di dalamnya. The http_build_querymenggantikan ruang dengan ditambah ( +) karakter.
Erfun
9

Saya akan menggunakan serialize()atau json_encode().

Meskipun tidak akan memberikan string hasil persis seperti yang Anda inginkan, akan lebih mudah untuk menyandikan / menyimpan / mengambil / mendekode nanti.

Hantu Madara
sumber
3

Menggunakan 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

Shiplu Mokaddim
sumber
1
Saya suka pendekatan array_walk, tapi saya tidak mengerti mengapa orang menyarankan untuk menggunakan create_functiondaripada hanya menggunakan fungsi anonim?
Rikki
@Rikki Kompatibilitas!
Shiplu Mokaddim
Ah! Saya tidak menyadari itu adalah hal PHP4!
Rikki
@Rikki ada . Ini hal pra-PHP 5.3. Fungsi anonim pertama kali muncul di PHP 5.3
Shiplu Mokaddim
Tapi itu diperkenalkan di PHP 4.0.1, begitu juga dengan PHP4. Semantik ... Menambahkan fitur sepenting fungsi anonim di pembaruan versi minor adalah hal yang aneh.
Rikki
2

Perubahan

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

jika Anda ingin menghidupkan kembali seluruh String tanpa lem $ terakhir

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

Dan penggunaannya:

$str = key_implode($yourArray, ",");
Björn
sumber
Saya mengerti bahwa ini adalah alternatif yang valid untuk menulis loop foreach setiap saat. DIUPVOTED;)
tony gil
2

Untuk tujuan debugging. Menulis berulang larik larik bersarang ke string. Digunakan untuk masing-masing. Fungsi menyimpan karakter Bahasa Nasional.

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
sumber
2

Anda juga bisa menggunakan array_reduce PHP ,

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

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

$imploded = array_reduce(array_keys($a), "acc");
sapenov.dll
sumber
1

Untuk membuat mysql dimana kondisi dari 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'))
Ajay Patidar
sumber
1

Ada juga var_export dan print_r yang lebih umum dikenal untuk mencetak keluaran debug tetapi kedua fungsi tersebut dapat menggunakan argumen opsional untuk mengembalikan string.

Menggunakan contoh pertanyaan sebagai data.

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

Menggunakan print_runtuk mengubah array menjadi string

Ini akan menghasilkan representasi variabel yang dapat dibaca manusia.

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

Akan menghasilkan:

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

Menggunakan var_exportuntuk mengubah array menjadi string

Yang akan menampilkan representasi string php dari variabel.

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

Akan menghasilkan:

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

Karena itu php valid kita bisa mengevaluasinya.

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

Keluaran:

bool(true)
nickl-
sumber
0

Berikut adalah contoh sederhana, menggunakan 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;
    }

}
Ivan Ferrer
sumber