วิธีการระเบิดอาร์เรย์ด้วยคีย์และค่าโดยไม่ต้อง foreach ใน PHP


113

ถ้าไม่มี foreachฉันจะเปลี่ยนอาร์เรย์แบบนี้ได้อย่างไร

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

เป็นสตริงแบบนี้

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

ฉันคิดเกี่ยวกับimplode()มันแล้ว แต่มันไม่ได้ระเบิดกุญแจด้วย

หากจำเป็นต้องทำก่อนเป็นไปได้ไหมที่จะไม่ทำรังส่วนหน้า?

แก้ไข:ฉันเปลี่ยนสตริงแล้ว


EDIT2 / UPDATE: คำถามนี้ถูกถามเมื่อไม่นานมานี้ ในเวลานั้นฉันต้องการเขียนทุกอย่างในบรรทัดเดียวดังนั้นฉันจะใช้ตัวดำเนินการ ternary และสร้างขึ้นในการเรียกฟังก์ชันเพื่อสนับสนุน foreach นั่นไม่ใช่แนวทางปฏิบัติที่ดี! เขียนโค้ดที่อ่านได้กระชับหรือไม่ไม่สำคัญขนาดนั้น

ในกรณีนี้: การใส่ foreach ในฟังก์ชันจะอ่านได้ง่ายและเป็นโมดูลมากกว่าการเขียนซับเดียว (แม้ว่าคำตอบทั้งหมดจะดีมากก็ตาม!)


foreach ที่ซ้อนกันจะเป็นอย่างไร?
Shubham

คุณกำลังทำอะไรอยู่? ทำไมคุณถึงมีข้อ จำกัด เหล่านั้น?
Madara's Ghost

นี่คือคลาสฐานข้อมูลของฉันสำหรับเว็บแอปที่ฉันกำลังสร้างฉันไม่ต้องการให้มันดูยุ่งเหยิงเพราะมันมีกลุ่ม foreach และ for-loop รวมกันอยู่แล้ว
tom91136

1
คำตอบที่เลือกนี้เป็นวิธีการที่คุณขออย่างไรก็ตามควรสังเกตว่ามันช้ากว่ามากและถ้าคุณจัดเก็บข้อมูลนี้ผ่านฐานข้อมูลจะดีกว่าอย่างมากสำหรับทั้ง loop และใช้ json_encode เท่านั้น จัดแสดง A: willem.stuursma.name/2010/11/22/…
กรณี

คำตอบ:


187

และอีกวิธีหนึ่ง:

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

หรือ:

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

6
วิธีนี้เป็นสิ่งที่ผู้เขียนต้องการ แต่ควรสังเกตว่ามันช้ากว่ามากและถ้าคุณจัดเก็บข้อมูลนี้ผ่านฐานข้อมูลจะดีกว่าอย่างมากสำหรับทั้ง loop และใช้ json_encode เท่านั้น จัดแสดง A: willem.stuursma.name/2010/11/22/…
กรณี

ดูเหมือนว่าลิงก์ที่นี่จะใช้งานไม่ได้อีกต่อไปecho "Hello, World!";ฉันควรเห็นตัวอย่างโค้ดของฟังก์ชันเหล่านั้นหรือไม่
Félix Gagnon-Grenier

วิธีนี้ง่ายมากที่จะปรับแต่งตามความต้องการของตัวเอง
Kabir Hossain

ฉันใช้วิธีนี้เพื่อสร้างตัวเลือกการเลือกและเติมข้อมูลตัวเลือกที่เลือกและเนื่องจากทั้งสองอาร์เรย์ต้องมีขนาดเท่ากันคุณจึงสามารถทำสิ่งนี้สำหรับอาร์เรย์ที่สองได้ array_fill(0, $input, 'selected-value-you want-to-check-against');สิ่งนี้จะสร้างอาร์เรย์ขนาดเดียวกันโดยมีค่าเดียวสำหรับทุกแถว
krasenslavov

188

คุณสามารถใช้http_build_queryเช่นนี้:

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

เอาท์พุต:

item1=object1, item2=object2 

การสาธิต


6
ไม่เคยใช้พารามิเตอร์อื่นของhttp_build_query.
Shiplu Mokaddim

16
+1 ใช่แล้วฉันชอบที่จะหานักเก็ตตัวน้อยที่ดีแบบนี้ :)
เบ็น

8
ระวังการเข้ารหัสสตริง! หากคุณไม่ได้สร้าง URL คุณอาจไม่ต้องการให้อยู่ในคีย์และค่าอาร์เรย์ของคุณ
Matteo

8
@Matteo คุณสามารถห่อhttp_build_queryในurldecodeการหลีกเลี่ยงมัน
Afterlame

3
โซลูชันอัจฉริยะ นั่นคือทั้งหมดที่ฉันต้องการสำหรับเอาต์พุตการดีบักของอาร์เรย์ am Assoc
dixus

34

ฉันใช้เวลาในการวัด (การทำซ้ำ 100000 ครั้ง) วิธีใดเร็วที่สุดในการติดอาร์เรย์เชื่อมโยง

วัตถุประสงค์:เพื่อให้ได้รายการ 1,000 รายการในรูปแบบนี้: "key: value, key2: value2"

เรามีอาร์เรย์ (ตัวอย่าง):

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

การทดสอบหมายเลขหนึ่ง:

ใช้http_build_queryและstr_replace :

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

เวลาเฉลี่ยในการระเบิดองค์ประกอบ 1,000 ชิ้น: 0.00012930955084904

การทดสอบหมายเลขสอง:

ใช้array_mapและการระเบิด :

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

เวลาเฉลี่ยในการระเบิดองค์ประกอบ 1,000 ชิ้น: 0.0004890081976675

การทดสอบหมายเลขสาม:

ใช้array_walkและการระเบิด :

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

เวลาเฉลี่ยในการระเบิดองค์ประกอบ 1,000 ชิ้น: 0.0003874126245348

การทดสอบหมายเลขสี่:

ใช้foreach :

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

เวลาเฉลี่ยในการระเบิดองค์ประกอบ 1,000 ชิ้น: 0.00026632803902445

ฉันสามารถสรุปได้ว่าวิธีที่ดีที่สุดในการติดอาร์เรย์ - ใช้ http_build_query และ str_replace


4
$s = ''; foreach ($array as $k=>$v) { if ($s !== null) { $s .= ','; } $s .= "{$k}:{$v}"; }ดีกว่าคนอื่น ๆ ทั้งหมด
Fleshgrinder

1
http_build_query bench ไม่มี urldecode ที่จะเปรียบเทียบกับส่วนอื่น ๆ
nickl-

อีกทางเลือกหนึ่ง:substr(str_replace('"', '', json_encode($headers)), 1, -1);
nickl-

1
ข้อควรระวัง: จะเปลี่ยนค่าของคุณหากมีช่องว่าง http_build_queryแทนที่ช่องว่างด้วยบวก ( +) ตัวละคร
Erfun

9

ฉันจะใช้serialize()หรือjson_encode().

แม้ว่าจะไม่ได้ให้สตริงผลลัพธ์ที่คุณต้องการ แต่การเข้ารหัส / จัดเก็บ / ดึงข้อมูล / ถอดรหัสในภายหลังจะง่ายกว่ามาก


3

ใช้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
ฉันชอบวิธี array_walk แต่ไม่เข้าใจว่าทำไมคนถึงแนะนำให้ใช้create_functionแทนที่จะใช้ฟังก์ชันนิรนาม?
Rikki

@ ริกกี้เข้ากันได้!
Shiplu Mokaddim

อา! ฉันไม่รู้ว่ามันเป็น PHP4!
Rikki

@Rikki ไม่มี สิ่งก่อน PHP 5.3 ฟังก์ชั่นไม่ระบุตัวตนปรากฏตัวครั้งแรกใน PHP 5.3
Shiplu Mokaddim

แต่มันถูกนำมาใช้ใน PHP 4.0.1 ดังนั้นจึงเป็น PHP4 ความหมาย ... การเพิ่มคุณสมบัติที่สำคัญเท่ากับฟังก์ชันที่ไม่ระบุชื่อในการอัปเดตเวอร์ชันรองเป็นเรื่องแปลก
Rikki

2

เปลี่ยน

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

หากคุณต้องการคืนค่าสตริงทั้งหมดโดยไม่มีกาว $ สุดท้าย

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

และการใช้งาน:

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

ฉันเข้าใจว่านี่เป็นทางเลือกที่ถูกต้องในการเขียน foreach loop ทุกครั้ง UPVOTED;)
tony gil

2

สำหรับวัตถุประสงค์ในการดีบัก Recursive เขียนอาร์เรย์ของอาร์เรย์ที่ซ้อนกันลงในสตริง ใช้ foreach. ฟังก์ชันจัดเก็บอักขระภาษาประจำชาติ

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

คุณสามารถใช้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");

1

สำหรับสร้าง mysql โดยที่เงื่อนไขจากอาร์เรย์

$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

นอกจากนี้ยังมีvar_exportและprint_rที่รู้จักกันทั่วไปสำหรับการพิมพ์เอาต์พุตดีบัก แต่ทั้งสองฟังก์ชันสามารถใช้อาร์กิวเมนต์ที่เป็นทางเลือกเพื่อส่งคืนสตริงแทน

โดยใช้ตัวอย่างจากคำถามเป็นข้อมูล

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

ใช้print_rเพื่อเปลี่ยนอาร์เรย์ให้เป็นสตริง

สิ่งนี้จะส่งออกการแสดงตัวแปรที่มนุษย์อ่านได้

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

จะส่งออก:

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

ใช้var_exportเพื่อเปลี่ยนอาร์เรย์ให้เป็นสตริง

ซึ่งจะส่งออกการแสดงสตริง php ของตัวแปร

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

จะส่งออก:

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

เนื่องจากเป็น php ที่ถูกต้องเราจึงสามารถประเมินได้

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

ผลลัพธ์:

bool(true)

0

นี่คือตัวอย่างง่ายๆโดยใช้คลาส:

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

}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.