#php #arrays #associative-array
#php #массивы #ассоциативный-массив
Вопрос:
Есть ли чистый способ упорядочить этот массив так, чтобы ключ стал идентификатором? Я делал это несколько раз, используя пару foreach и новый массив, куда я помещаю информацию, но я использую около 7 строк кода, и мне было интересно, есть ли что-нибудь чище. Рассматриваемый массив:
Array (
[0] => Array ( [log_id] => 6 [type] => Test [other_info] => MoreInfo )
[1] => Array ( [log_id] => 5 [type] => Test2 [other_info] => MoreInfo2 )
)
Итак, что я хочу получить из приведенного выше массива:
Array (
[6] => Array ( [type] => Test [other_info] => MoreInfo )
[5] => Array ( [type] => Test2 [other_info] => MoreInfo2 )
)
Вы можете видеть, что теперь я ввел идентификатор журнала в качестве ключа. Это занимает у меня несколько строк кода… У вас есть представление о том, как этого можно достичь максимум за 3 или 4 строки?
В качестве альтернативы, есть ли более чистый способ доступа к строке, содержащей * log_id *, который я хочу? Использование, которое я хочу дать этому, заключается в том, что я могу получить доступ к строке определенного * log_id * … В этом случае я бы сделал это с $array[$log_id]
помощью … Но если есть решение сделать это без изменения массива (и только с 1 строкой) Я тоже приму это как ответ!
Спасибо!
Комментарии:
1. Есть ли какая-либо причина, по которой вы не можете изначально создать массив с log_id вместо его преобразования?
2. Он поступает из запроса SELECT * FROM … Я не думаю, что смогу, насколько я знаю.
Ответ №1:
Вы не должны беспокоиться о строках кода, которые, элегантный код самодокументируется, что означает, что вы можете прочитать его и понять, что он делает. И он содержит необходимый минимум строк, что обычно занимает больше времени для написания кода.
Противоположность элегантному коду — сжатый, загадочный код, подобный этому, который делает то, что вам нужно для рассматриваемого массива (я вставил его в $data
, Demo):
$data = array_reduce($data, function($v, $w) { $v[array_shift($w)] = $w; return $v;});
Это всего лишь одна строка кода, но она не элегантна.
Это можно было бы прочитать намного лучше:
/**
* You can leave a comment here.
* @return array $data keyed with first value of each value
*/
function first_as_key(Array $data)
{
$keyed = array();
foreach($data as $v)
$keyed[array_shift($v)] = $v
;
return $keyed;
}
Чаще всего гораздо лучше иметь данные под рукой в форме, которая не требует их транспонирования. Кроме того, если вам нужно выполнить транспонирование, создайте себе функцию, которая сделает эту работу за вас.
Ответ №2:
Но зачем вам нужно несколько операторов foreach? Разве это не ответило бы на ваш вопрос:
$new_arr = array();
foreach ($old_arr as $row) {
$new_arr[$row['log_id']][] = $row;
}
Единственное отличие заключается в том, что новые строки по-прежнему будут иметь ключ log_id, но я сомневаюсь, что это вас беспокоит. За исключением этого, я нахожу это очень понятным.
Комментарии:
1. да .. вот как я это делаю… но некоторые из них имеют несколько fors, если бы у меня был результат, в котором log_id, например, повторяется, и мне нужно создать другой массив внутри ключа log_id для хранения всех данных с этим log_id.
2. Ах, я понимаю, почему у вас изначально была проблема. Но это легко исправить, и я обновил свой пример, чтобы включить его: я добавил,
[]
чтобы $new_arr[log_id] всегда был массивом (иногда в нем может быть только один элемент / строка, но, на мой взгляд, это нормально — вы действительно сможете обработатьих унитарно). Дайте мне знать, если это сработает для вас.3. Кстати, решения с использованием array_map и т. Д. этот вариант использования выглядел бы очень некрасиво (если вообще возможно реализовать).
Ответ №3:
Я не уверен, что есть хороший способ сделать это и не создавать новый массив (поскольку, если вы просто работаете с существующим массивом, у вас могут возникнуть коллизии ключей (в вашем примере, что произойдет, если первый элемент будет иметь log_id 1?)
Это можно поместить в одну строку, используя create_function
функцию php, но это довольно плохо для удобства чтения. Все, что у вас есть, используя 6 или 7 строк, вероятно, лучший способ сделать это.
Но ради аргумента, вот один из способов сделать это в 2 строки, используя array_walk:
<?php
$test = array();
$test[] = array('id' => 6, 'data' => 'asdf');
$test[] = array('id' => 7, 'data' => 'qwer');
print_r($test);
$result = array();
array_walk($test, create_function('amp;$val,$key', 'global $resu< $result[$val['id']] = $val;'));
print_r($result);
?>
Из любопытства, как вы создаете массив? Если он поступает из какой-либо базы данных, вероятно, лучше создать ключ при добавлении записи.