Як застосувати масив з ключем і значенням без виступу в PHP


111

Як не передбачити , як я можу перетворити такий масив

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

до такої струни

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

Я implode()вже думав про це , але це не перешкоджає ключу.

Якщо проповідувати це потрібно, чи можна не гніздити передбачення?

EDIT: Я змінив рядок


EDIT2 / UPDATE: Це питання задавали досить давно. У той час я хотів записати все в один рядок, щоб я використовував потрійні оператори та вбудовані в гніздо функції на користь foreach. Це була не дуже добра практика! Напишіть код, який читається, будь то лаконічний чи ні, не має великого значення.

У цьому випадку: введення функції foreach у функцію буде набагато легше читати та модульно, ніж писати однолінійку (Хоча всі відповіді чудові!).


Яким чином вкладене передбачення буде необхідним?
Шубхам

Що ти робиш? Чому у вас є ці обмеження?
Привид

це був мій клас баз даних для веб-додатків, які я будую, я не хочу, щоб він виглядав безладним, оскільки він уже заповнений купою передбачень і разом-петлі всі разом
tom91136

1
Ця обрана відповідь - це метод, про який ви просили, однак слід зазначити, що це критично повільніше, і якщо ви зберігаєте цю інформацію через базу даних, вона буде набагато перевершена як циклом, так і просто використовувати json_encode. Виставка А: 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
Цей метод вимагав автор, але слід зазначити, що він критично повільніше, і якщо ви зберігаєте цю інформацію через базу даних, вона буде набагато перевершена як циклом, так і просто використовувати json_encode. Виставка A: willem.stuursma.name/2010/11/22/…
Справа

Жодне з посилань тут, здається, не працює більше, всі вони echo "Hello, World!";Чи повинен я бачити приклади коду цих функцій?
Фелікс Ганьон-Греньє

Цей спосіб дуже легко налаштувати відповідно до власних потреб.
Кабір Хоссайн

Я використовував цей метод для побудови параметрів вибору та заповнення вибраного параметра, і оскільки обидва масиви повинні бути однакового розміру, ви можете зробити щось подібне для другого масиву. array_fill(0, $input, 'selected-value-you want-to-check-against');Це створить масив однакового розміру з одним значенням для всіх рядків.
krasenslavov

187

Ви можете використовувати http_build_query , як-от так:

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

Вихід:

item1=object1, item2=object2 

Демо


5
Ніколи не використовували інші параметри http_build_query.
Шиплу Мокаддім

16
+1 Пекло так, я люблю знайти такі маленькі самородки добра:
Бен

8
Остерігайтеся кодування рядків! Якщо ви не створюєте URL-адресу, можливо, ви не хочете, щоб він був у вашому ключі та значенні масиву
Маттео,

8
@Matteo Ви можете обернути http_build_queryв , urldecodeщоб уникнути цього.
Aftermeame

3
Геніальне рішення. Це було все, що мені було потрібно для виводу налагодження масиву am assoc.
dixus

33

Я провів вимірювання (100000 ітерацій), який найшвидший спосіб склеїти асоціативний масив?

Мета: Отримати рядок з 1000 елементів у такому форматі: "ключ: значення, ключ2: значення2"

У нас є масив (наприклад):

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

Тест номер один:

Використовуйте http_build_query та str_replace :

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

Середній час для імплодування 1000 елементів: 0.00012930955084904

Тест номер два:

Використовуйте array_map та implode :

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

Середній час для імплодування 1000 елементів: 0.0004890081976675

Тест номер три:

Використовуйте array_walk та implode :

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

Середній час імпровізації 1000 елементів: 0.0003874126245348

Тест номер чотири:

Використовуйте функцію foreach :

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

Середній час для імплодування 1000 елементів: 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 відсутній 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);

ІДЕЙОН


1
Мені подобається підхід array_walk, але я не розумію, чому люди пропонують використовувати create_functionзамість того, щоб просто використовувати анонімну функцію?
Ріккі

Сумісність @Rikki!
Шиплу Мокаддім

Ах! Я не розумів, що це була річ PHP4!
Рікі

@Rikki Ні . Її попередньо PHP 5.3 річ. Анонімна функція вперше з'явилася на PHP 5.3
Шиплу Мокаддім

Але він був представлений у PHP 4.0.1, так це і є PHP4. Семантика ... Додавання функції, такої важливої, як анонімні функції, в оновлення незначної версії є химерним.
Рікі

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, ",");

Я розумію, що це дійсна альтернатива написанню циклу передбачень кожного разу. ПОВЕРНЕНО;)
tony gil

2

Для налагодження. Рекурсивно записувати масив вкладених масивів у рядок. Використовуваний 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;
    }

}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.