Làm thế nào để mã hóa mảng với khóa và giá trị mà không cần foreach trong PHP


111

Nếu không có foreach , làm thế nào tôi có thể biến một mảng như thế này

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

thành một chuỗi như thế này

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

Tôi đã nghĩ đến implode()rồi, nhưng nó không giải mã được chìa khóa với nó.

Nếu cần foreach thì có thể không lồng foreach không?

CHỈNH SỬA: Tôi đã thay đổi chuỗi


EDIT2 / UPDATE: Câu hỏi này đã được hỏi cách đây khá lâu. Vào thời điểm đó, tôi muốn viết mọi thứ trong một dòng vì vậy tôi sẽ sử dụng các toán tử bậc ba và tổ hợp được xây dựng trong các lệnh gọi hàm có lợi cho foreach. Đó không phải là một thực hành tốt! Viết mã có thể đọc được, nó có ngắn gọn hay không không quan trọng lắm.

Trong trường hợp này: đặt foreach trong một hàm sẽ dễ đọc và dễ hiểu hơn nhiều so với viết một dòng (Mặc dù tất cả các câu trả lời đều tuyệt vời!).


Foreach lồng nhau sẽ là necesarry như thế nào?
Shubham,

Bạn đang cố gắng gì Tại sao bạn có những ràng buộc đó?
ma của Madara

này là lớp cơ sở dữ liệu của tôi cho ứng dụng web tôi đang xây dựng, tôi không muốn nó nhìn lộn xộn kể từ khi nó đã được dân cư với một loạt các foreach và cho vòng tất cả cùng nhau
tom91136

1
Câu trả lời đã chọn này là phương pháp mà bạn đã yêu cầu, tuy nhiên cần lưu ý rằng nó chậm hơn rất nhiều và nếu bạn đang lưu trữ thông tin này qua cơ sở dữ liệu thì nó sẽ vượt trội hơn rất nhiều so với cả một vòng lặp và điều này chỉ sử dụng json_encode. Biểu đồ A: willem.stuursma.name/2010/11/22/…
Trường hợp

Câu trả lời:


187

và một cách khác:

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

hoặc là:

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

6
Phương pháp này là những gì Tác giả yêu cầu, nhưng cần lưu ý rằng nó rất chậm hơn và nếu bạn đang lưu trữ thông tin này qua cơ sở dữ liệu thì nó sẽ vượt trội hơn rất nhiều so với cả một vòng lặp và điều này chỉ cần sử dụng json_encode. Biểu đồ A: willem.stuursma.name/2010/11/22/…
Trường hợp

Không có liên kết nào ở đây dường như hoạt động nữa, tất cả chúng echo "Hello, World!";Tôi có nên xem các ví dụ mã của các hàm đó không?
Félix Gagnon-Grenier,

Phương pháp này rất dễ dàng để tùy chỉnh theo nhu cầu riêng.
Kabir Hossain

Tôi đang sử dụng phương pháp này để xây dựng các tùy chọn được chọn và điền tùy chọn đã chọn và vì cả hai mảng phải có cùng kích thước nên bạn có thể làm điều gì đó như thế này cho mảng thứ hai. array_fill(0, $input, 'selected-value-you want-to-check-against');Điều này sẽ tạo ra mảng kích thước giống nhau với một giá trị duy nhất cho tất cả các hàng.
krasenslavov

187

Bạn có thể sử dụng http_build_query , như thế này:

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

Đầu ra:

item1=object1, item2=object2 

Bản giới thiệu


5
Chưa bao giờ sử dụng các tham số khác của http_build_query.
Shiplu Mokaddim,

16
1 Hell yeah Tôi thích tìm cốm nhỏ của lòng tốt như :) này
Bến

8
Cẩn thận với các mã hóa chuỗi Nếu bạn không xây dựng một URL có thể bạn không muốn nó trên chính mảng của bạn & giá trị!
Matteo

8
@Matteo Bạn có thể bọc http_build_querytrong urldecodeđể tránh nó.
Afterlame

3
Giải pháp thiên tài. Đó là tất cả những gì tôi cần cho một đầu ra gỡ lỗi của mảng am assoc.
dixus

33

Tôi đã sử dụng các phép đo (100000 lần lặp), cách nhanh nhất nào để tạo một mảng liên kết?

Mục tiêu: Để có được một dòng gồm 1.000 mục, ở định dạng sau: "key: value, key2: value2"

Chúng tôi có mảng (ví dụ):

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

Bài kiểm tra số một:

Sử dụng http_build_querystr_replace :

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

Thời gian trung bình để giải mã 1000 phần tử: 0,00012930955084904

Bài kiểm tra số hai:

Sử dụng array_mapimplode :

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

Thời gian trung bình để giải mã 1000 phần tử: 0,0004890081976675

Bài kiểm tra số ba:

Sử dụng array_walkimplode :

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

Thời gian trung bình để giải mã 1000 phần tử: 0,0003874126245348

Bài kiểm tra số bốn:

Sử dụng foreach :

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

Thời gian trung bình để giải mã 1000 phần tử: 0,00026632803902445

Tôi có thể kết luận rằng cách tốt nhất để gắn mảng - sử dụng http_build_query và str_replace


4
$s = ''; foreach ($array as $k=>$v) { if ($s !== null) { $s .= ','; } $s .= "{$k}:{$v}"; }vượt trội hơn tất cả những người khác.
Fleshgrinder

1
Băng ghế dự bị http_build_query thiếu mã urldecode để so sánh với các mã khác.
nickl-

Một lựa chọn khác:substr(str_replace('"', '', json_encode($headers)), 1, -1);
nickl- Ngày

1
THẬN TRỌNG: Nó thay đổi các giá trị của bạn nếu có khoảng trống trong đó. Dấu http_build_querycách thay thế bằng +ký tự dấu cộng ( ).
Erfun

9

Tôi sẽ sử dụng serialize()hoặc json_encode().

Mặc dù nó sẽ không cung cấp cho bạn chuỗi kết quả chính xác mà bạn muốn, nhưng việc mã hóa / lưu trữ / truy xuất / giải mã sau này sẽ dễ dàng hơn nhiều.


3

Sử dụng 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
Tôi thích cách tiếp cận array_walk, nhưng tôi không hiểu tại sao mọi người đề xuất sử dụng create_functionthay vì chỉ sử dụng một hàm ẩn danh?
Rikki

Khả năng tương thích @Rikki!
Shiplu Mokaddim

Ah! Tôi không nhận ra đó là một thứ PHP4!
Rikki

@Rikki Không . Điều trước PHP 5.3 của nó. Hàm ẩn danh xuất hiện lần đầu trên PHP 5.3
Shiplu Mokaddim

Nhưng nó đã được giới thiệu trong PHP 4.0.1, một thứ PHP4 cũng vậy. Ngữ nghĩa ... Thêm một tính năng quan trọng như các chức năng ẩn danh trong bản cập nhật phiên bản nhỏ là điều kỳ lạ.
Rikki

2

Thay đổi

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

nếu bạn muốn phục hồi toàn bộ Chuỗi mà không cần keo $ cuối cùng

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

Và cách sử dụng:

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

tôi hiểu rằng đây là một giải pháp thay thế hợp lệ để viết một vòng lặp foreach mọi lúc. ĐÃ CẬP NHẬT;)
tony gil

2

Đối với mục đích gỡ lỗi. Viết đệ quy một mảng các mảng lồng nhau vào một chuỗi. Đã sử dụng foreach. Hàm lưu trữ các ký tự Quốc ngữ.

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

Bạn cũng có thể sử dụng array_reduce của PHP ,

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

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

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

1

Để tạo mysql trong đó điều kiện từ mảng

$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

Ngoài ra còn có var_exportprint_r thường được biết đến nhiều hơn để in đầu ra gỡ lỗi nhưng cả hai hàm đều có thể nhận một đối số tùy chọn để trả về một chuỗi thay thế.

Sử dụng ví dụ từ câu hỏi làm dữ liệu.

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

Sử dụng print_rđể biến mảng thành một chuỗi

Điều này sẽ tạo ra một biểu diễn có thể đọc được của con người của biến.

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

Sẽ xuất:

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

Sử dụng var_exportđể biến mảng thành một chuỗi

Điều này sẽ xuất ra một biểu diễn chuỗi php của biến.

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

Sẽ xuất:

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

Bởi vì nó là php hợp lệ, chúng tôi có thể đánh giá nó.

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

Kết quả đầu ra:

bool(true)

0

Đây là một ví dụ đơn giản, sử dụng 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;
    }

}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.