如何将数组或对象数组转换为关联数组?

时间:2012-07-19 14:34:22

标签: php array-map

我习惯于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's 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迭代一个简单的循环,并且对于每个密钥,检查它是否有前缀,如果是这样,将它及其值弹出到数组上)

4 个答案:

答案 0 :(得分:33)

前几天我遇到了完全相同的问题。使用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" }

答案 1 :(得分: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;
}

答案 2 :(得分:2)

这是对我在公认方法中的评论的澄清。希望更容易阅读。这是来自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()加上自定义插入语句强制解决问题。

尼斯!

答案 3 :(得分:1)

yield运算符的好用例!

$arr = array('a','b','c','d');

$fct = function(array $items) {
            foreach($items as $letter)
            {
                yield sprintf("key-%s",
                    $letter
                ) => "yes";
            }
        };

$newArr = iterator_to_array($fct($arr));

给出:

array(4) {
  'key-a' =>
  string(3) "yes"
  'key-b' =>
  string(3) "yes"
  'key-c' =>
  string(3) "yes"
  'key-d' =>
  string(3) "yes"
}