PHP'de foreach olmadan anahtar ve değer içeren dizi nasıl yerleştirilir


112

Foreach olmadan , böyle bir diziyi nasıl döndürebilirim

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

böyle bir dizeye

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

implode()Zaten düşündüm , ama bununla anahtarı patlatmıyor.

Her zaman gerekliyse, önü iç içe geçirmemek mümkün müdür?

DÜZENLEME: Dizeyi değiştirdim


DÜZENLEME / GÜNCELLEME: Bu soru epey bir süre önce soruldu. O zamanlar, her şeyi tek satırda yazmak istedim, böylece üçlü operatörler kullanacak ve foreach lehine yerleşik işlev çağrılarını yerleştirecektim. Bu iyi bir uygulama değildi! Okunabilir bir kod yazın, kısa olsun ya da olmasın o kadar da önemli değil.

Bu durumda: foreach'i bir işleve koymak, tek satırlık bir yazı yazmaktan çok daha okunaklı ve modüler olacaktır (Tüm yanıtlar harika olsa bile!).


Ne kadar iç içe geçmiş bir evlenmek gerekir?
Shubham

Ne deniyorsun Neden bu kısıtlamalara sahipsiniz?
Madara's Ghost

bu benim oluşturduğum web uygulaması için veritabanı sınıfımdı, zaten bir sürü foreach ve for-loop ile dolu olduğu için dağınık görünmesini istemiyorum
tom91136

1
Bu seçili cevap, istediğiniz yöntemdir, ancak önemli ölçüde daha yavaş olduğu ve bu bilgiyi bir veritabanı aracılığıyla depoluyorsanız, hem bir döngüden hem de sadece json_encode'u kullanmanın çok daha üstün olacağı unutulmamalıdır. Ek A: willem.stuursma.name/2010/11/22/…
Dava

Yanıtlar:


187

ve başka bir yol:

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

veya:

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

6
Bu yöntem, Yazarın istediği şeydir, ancak kritik derecede daha yavaş olduğu ve bu bilgiyi bir veritabanı aracılığıyla depoluyorsanız, hem bir döngüden hem de sadece json_encode'u kullanmaktan çok daha üstün olacağı unutulmamalıdır. Ek A: willem.stuursma.name/2010/11/22/…
Dava

Buradaki bağlantıların hiçbiri artık çalışmıyor, hepsi echo "Hello, World!";bu işlevlerin kod örneklerini görmeli miyim?
Félix Gagnon-Grenier

Bu yöntemin kendi talebine göre özelleştirilmesi çok kolaydır.
Kabir Hossain

Bu yöntemi seçme seçenekleri oluşturmak ve seçilen seçeneği doldurmak için kullanıyordum ve her iki dizinin de aynı boyutta olması gerektiğinden, ikinci dizi için böyle bir şey yapabilirsiniz. array_fill(0, $input, 'selected-value-you want-to-check-against');Bu, tüm satırlar için tek değerli aynı boyutta dizi oluşturacaktır.
krasenslavov

188

Http_build_query'yi şu şekilde kullanabilirsiniz :

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

Çıktı:

item1=object1, item2=object2 

gösteri


6
Diğer parametrelerini hiç kullanmadım http_build_query.
Shiplu Mokaddim

16
+1 Cehennem evet, bunun gibi küçük iyilik külçeleri bulmayı seviyorum :)
Ben

8
Dize kodlamasına dikkat edin! Bir URL oluşturmuyorsanız, onu dizi anahtarınızda ve değerinizde istemiyor olabilirsiniz
Matteo

8
Sen sarabilirsiniz @Matteo http_build_queryiçinde urldecodebunu önlemek için.
Afterlame

3
Dahi çözüm. Am assoc dizisinin hata ayıklama çıktısı için ihtiyacım olan tek şey buydu.
dixus

33

Ölçümleri (100000 yineleme) harcadım, bir ilişkisel diziyi yapıştırmanın en hızlı yolu nedir?

Amaç: Bu biçimde 1.000 öğelik bir satır elde etmek için: "anahtar: değer, anahtar2: değer2"

Bir dizimiz var (örneğin):

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

Birinci test:

Http_build_query ve str_replace kullanın :

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

1000 elementi patlatmak için ortalama süre: 0.00012930955084904

İkinci test:

Array_map ve implode kullanın :

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

1000 elementi patlatmak için ortalama süre: 0.0004890081976675

Üçüncü test:

Array_walk ve implode kullanın :

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

1000 elementi patlatmak için ortalama süre: 0.0003874126245348

Dördüncü test:

Foreach'i kullanın :

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

1000 elementi patlatmak için ortalama süre: 0.00026632803902445

Diziyi yapıştırmanın en iyi yolunun http_build_query ve str_replace kullanacağı sonucuna varabilirim.


4
$s = ''; foreach ($array as $k=>$v) { if ($s !== null) { $s .= ','; } $s .= "{$k}:{$v}"; }diğerlerinden daha iyi performans gösterir.
Fleshgrinder

1
Http_build_query tezgahında diğerleriyle karşılaştırmak için urldecode eksik.
nickl-

Başka bir seçenek:substr(str_replace('"', '', json_encode($headers)), 1, -1);
nickl-

1
DİKKAT: İçinde boşluk varsa değerlerinizi değiştirir. http_build_queryArtı (boşlukların yerini +) karakter.
Erfun

9

serialize()Veya kullanırdım json_encode().

İstediğiniz kesin sonuç dizesini vermeyecek olsa da, daha sonra kodlamak / depolamak / almak / kodunu çözmek çok daha kolay olacaktır.


3

Array_walk kullanma

$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
Array_walk yaklaşımını seviyorum, ancak insanların neden create_functionsadece anonim bir işlev kullanmak yerine kullanmayı önerdiklerini anlamıyorum ?
Rikki

@Rikki Uyumluluğu!
Shiplu Mokaddim

Ah! Bunun bir PHP4 olayı olduğunu bilmiyordum!
Rikki

@Rikki Hayır . PHP 5.3 öncesi şey. Anonim işlev ilk olarak PHP 5.3'te ortaya çıktı
Shiplu Mokaddim

Ancak PHP 4.0.1'de tanıtıldı, bir PHP4 şey de öyle. Anlambilim ... Küçük bir sürüm güncellemesine anonim işlevler kadar önemli bir özellik eklemek tuhaftır.
Rikki

2

Değişiklik

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

son $ yapıştırıcısı olmadan tüm String'i yeniden yaşamak istiyorsanız

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

Ve kullanım:

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

Bunun her seferinde bir foreach döngüsü yazmaya geçerli bir alternatif olduğunu anlıyorum. YÜKSELTİLDİ;)
tony gil

2

Hata ayıklama amacıyla. Özyinelemeli, bir dizeye iç içe dizilerden oluşan bir dizi yazın. Foreach kullanılır. İşlev, Ulusal Dil karakterlerini depolar.

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

PHP'nin array_reduce işlevini de kullanabilirsiniz ,

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

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

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

1

Dizideki koşulların bulunduğu mysql oluşturmak için

$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

Ayrıca var_export ve print_r daha yaygın olarak hata ayıklama çıktısını yazdırmakla bilinir, ancak her iki işlev de bir dizge döndürmek için isteğe bağlı bir argüman alabilir.

Sorudaki örneği veri olarak kullanmak.

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

print_rDiziyi bir dizeye dönüştürmek için kullanma

Bu, değişkenin insan tarafından okunabilir bir gösterimini verecektir.

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

Çıktı:

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

var_exportDiziyi bir dizeye dönüştürmek için kullanma

Bu, değişkenin bir php dizge gösterimini çıkarır.

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

Çıktı:

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

Geçerli php olduğu için değerlendirebiliriz.

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

Çıktılar:

bool(true)

0

İşte class kullanan basit bir örnek:

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

}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.