Как преобразовать массив массивов или объектов в ассоциативный массив?

Я использую функцию perl map(), где обратный вызов может назначать как ключ, так и значение, создавая таким образом ассоциативный массив, где вход был плоским массивом. Я знаю array_fill_keys(), который может быть полезен, если все, что вы хотите сделать, это создать хеш-стиль в словаре, но что, если вы не обязательно хотите все значения должны быть одинаковыми? Очевидно, что все может быть выполнено с помощью итерации foreach, но какие существуют другие (возможно, более элегантные) методы?

Изменить: добавление примера, чтобы прояснить преобразование. Пожалуйста, не зацикливайтесь на преобразовании, вопрос заключается в преобразовании плоского списка в хэш, где мы не можем предположить, что все значения будут одинаковыми.

$original_array: ('a', 'b', 'c', 'd')
$new_hash: ('a'=>'yes', 'b'=>'no', 'c'=>'yes', 'd'=>'no')

*note: the values in this example are arbitrary, governed by some business logic that is not really relevant to this question. For example, perhaps it based on the even-oddness of the ordinal value of the key

Пример реального мира Таким образом, используя ответ, который был представлен здесь, вы можете проанализировать через $_POST, чтобы получить список только тех полей ввода, которые соответствуют заданным критериям. Это может быть полезно, например, если у вас много полей ввода в вашей форме, но определенная группа из них должна обрабатываться вместе.

В этом случае у меня есть несколько полей ввода, которые представляют отображения в базу данных. Каждое из полей ввода выглядит следующим образом: <input name="field-user_email" value="2" />, где каждый из этого типа поля имеет префикс "field -".

то, что мы хотим сделать, это, во-первых, получить список только тех полей ввода, которые на самом деле начинаются с "field-", тогда мы хотим создать ассоциативный массив с именем $mapped_fields, который имеет извлеченное имя поля в качестве ключа и фактическое значение поля ввода в качестве значения.

$mapped_fields = array_reduce( preg_grep( '/field-.+/', array_keys( $_POST ) ), function( $hash, $field ){ $hash[substr( $field, 6 )] = $_POST[$field]; return $hash; } );

Какие выходы:

Array ( [date_of_birth] => 1 [user_email] => 2 [last_name] => 3 [first_name] => 4 [current_position] => 6 )

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

Ответ 1

У меня была такая же проблема несколько дней назад. Невозможно использовать array_map, но array_reduce делает трюк.

$arr = array('a','b','c','d');
$assoc_arr = array_reduce($arr, function ($result, $item) {
    $result[$item] = (($item == 'a') || ($item == 'c')) ? 'yes' : 'no';
    return $result;
}, array());
var_dump($assoc_arr);

результат:

array(4) { ["a"]=> string(3) "yes" ["b"]=> string(2) "no" ["c"]=> string(3) "yes" ["d"]=> string(2) "no" }

Ответ 2

Насколько я знаю, это невозможно в одном выражении, поэтому вы можете использовать цикл foreach, à la

$new_hash = array();

foreach($original_array as $item) {
    $new_hash[$item] = 'something';
}

Если вам нужно это в одном выражении, продолжайте и выполните функцию:

function array_map_keys($callback, $array) {
    $result = array();

    foreach($array as $item) {
        $r = $callback($item);

        $result[$r[0]] = $r[1];
    }

    return $result;
}

Ответ 3

Это пояснение к моему комментарию в принятом методе. Надеюсь, читать легче. Это из класса WordPress, поэтому ссылка $wpdb для записи данных:

class SLPlus_Locations {
    private $dbFields = array('name','address','city');

    public function MakePersistent() {
        global $wpdb;
        $dataArray = array_reduce($this->dbFields,array($this,'mapPropertyToField'));
        $wpdb->insert('wp_store_locator',$dataArray);
    }

    private function mapPropertyToField($result,$property) {
        $result[$property] = $this->$property;
        return $result;
    }
}

Очевидно, что для полного решения есть немного больше, но присутствуют элементы, относящиеся к array_reduce(). Легче читать и более элегантно, чем foreach или заставлять проблему с помощью array_map() плюс пользовательский оператор insert.

Ницца!