Упорядоченный массив в ассоциативный массив, нечетные значения в качестве ключей - PullRequest
4 голосов
/ 09 марта 2011

Довольно просто:

// turn
array('foo', 'bar', 'hello', 'world');

// into
array('foo' => 'bar', 'hello' => 'world');

Сейчас я использую:

do{
    $arrayOut[current($arrayIn)] = next($arrayIn);
}while(next($arrayIn));

Мне интересно, есть ли способ сделать это без промежуточной переменной, $arrayOut,Я мог бы написать функцию, однако это единственный вариант использования, и я стараюсь, чтобы мой сценарий не загромождался.Мне просто интересно, есть ли что-то, что я пропустил в документах, которые послужили бы этой цели.


Значения берутся из пути маршрутизации:

route/to/controller/action/key1/value1/key2/value2

Он взорван, ив конце концов, после использования других компонентов, я остаюсь с ('key1', 'value1', 'key2', 'value2', ...)


Спасибо вам за понимание и предложения. Длинные уши выиграл это за лаконичный подход, который при расширении до более чем "1 строки" не очень загадочно (я не думаю, по крайней мере)

Однако, также сЧто касается предположения Long Ears ', возможно, мое желание семантически точного кода с минимальной многословностью одолело меня, и я гонялся за маргаритками, пытаясь сохранить переменную область действия "свободной от загрязнений", перефразируя себя.

Ответы [ 4 ]

5 голосов
/ 09 марта 2011

Вы можете сделать свой существующий код немного более эффективным (удаляет один вызов функции за итерацию, за один в начале:)

$b = array();
array_unshift($a, false);
while (false !== $key = next($a)) {
    $b[$key] = next($a);
}

Хорошо, ( вздрогнул ) вот ваш один вкладыш:

$b = call_user_func_array('array_merge', array_map(function($v) { return array($v[0] => $v[1]); }, array_chunk($a, 2)));
3 голосов
/ 31 июля 2017

Вам не нужен массив, вы можете сделать это напрямую с текстом пути:

$path = "foo/bar/hello/world";

preg_match_all("#(?J)(?<key>[^/]+)/(?<val>[^/]*)#", $path, $p);
$params = array_combine($p['key'], $p['val']);

print_r($params);
/*
Array
(
    [foo] => bar
    [hello] => world
)
*/
2 голосов
/ 09 марта 2011

Я не думаю, что вы можете сделать лучше, чем у вас есть.Но как насчет попытки поместить нечетные и четные элементы в разные массивы, когда ваш ввод читается?Затем вы можете использовать array_combine для создания однострочного.

Обновление : array_map не поможет, так как будет создан массив сравное количество элементов.Вы можете делать вещи с array_filter и array_combine, но опять же, это не будет короче.

Мне действительно нравится то, что у вас есть;Короче говоря, просто, делает работу.Я просто преобразовал бы его в функцию, скажем, array_interleave_combine или что-то подобное.

Обновление 2 :

Ну, вы просили об этом, поэтому здесьэто.Пытается быть слишком умным, если вы спросите меня.Это однострочник, но я действительно не думаю, что «чистоты» этого достаточно, чтобы окупить потерянное время, когда кому-то понадобится понять, что происходит:

$result = array_reduce(
    array('foo', 'bar', 'hello', 'world'),
    function($partial, $item) {
        static $nextKey;
        if ($nextKey === null) {
            $nextKey = $item;
        }
        else {
            $partial[$nextKey] = $item;
            $nextKey = null;
        }

        return $partial;
    });
1 голос
/ 09 марта 2011

Для этого решения не требуется дополнительный массив:

$arr = array('foo', 'bar', 'hello', 'world');

for($i = 0, $count = count($arr); $i < $count; $i += 2)
{
  $arr[$arr[$i]] = $arr[$i + 1];
  unset($arr[$i], $arr[$i + 1]);
}
...