PHP's array_map including keys

前端 未结 18 2697
抹茶落季
抹茶落季 2020-11-30 19:31

Is there a way of doing something like this:

$test_array = array(\"first_key\" => \"first_value\", 
                    \"second_key\" => \"second_valu         


        
相关标签:
18条回答
  • 2020-11-30 19:54
    $array = [
      'category1' => 'first category',
      'category2' => 'second category',
    ];
     
    $new = array_map(function($key, $value) {
      return "{$key} => {$value}";
    }, array_keys($array), $array);
    
    0 讨论(0)
  • 2020-11-30 20:01

    I'll add yet another solution to the problem using version 5.6 or later. Don't know if it's more efficient than the already great solutions (probably not), but to me it's just simpler to read:

    $myArray = [
        "key0" => 0,
        "key1" => 1,
        "key2" => 2
    ];
    
    array_combine(
        array_keys($myArray),
        array_map(
            function ($intVal) {
                return strval($intVal);
            },
            $myArray
        )
    );
    

    Using strval() as an example function in the array_map, this will generate:

    array(3) {
      ["key0"]=>
      string(1) "0"
      ["key1"]=>
      string(1) "1"
      ["key2"]=>
      string(1) "2"
    }
    

    Hopefully I'm not the only one who finds this pretty simple to grasp. array_combine creates a key => value array from an array of keys and an array of values, the rest is pretty self explanatory.

    0 讨论(0)
  • 2020-11-30 20:02

    This is probably the shortest and easiest to reason about:

    $states = array('az' => 'Arizona', 'al' => 'Alabama');
    
    array_map(function ($short, $long) {
        return array(
            'short' => $short,
            'long'  => $long
        );
    }, array_keys($states), $states);
    
    // produces:
    array(
         array('short' => 'az', 'long' => 'Arizona'), 
         array('short' => 'al', 'long' => 'Alabama')
    )
    
    0 讨论(0)
  • 2020-11-30 20:02

    YaLinqo library* is well suited for this sort of task. It's a port of LINQ from .NET which fully supports values and keys in all callbacks and resembles SQL. For example:

    $mapped_array = from($test_array)
        ->select(function ($v, $k) { return "$k loves $v"; })
        ->toArray();
    

    or just:

    $mapped_iterator = from($test_array)->select('"$k loves $v"');
    

    Here, '"$k loves $v"' is a shortcut for full closure syntax which this library supports. toArray() in the end is optional. The method chain returns an iterator, so if the result just needs to be iterated over using foreach, toArray call can be removed.

    * developed by me

    0 讨论(0)
  • 2020-11-30 20:03

    I made this function, based on eis's answer:

    function array_map_($callback, $arr) {
        if (!is_callable($callback))
            return $arr;
    
        $result = array_walk($arr, function(&$value, $key) use ($callback) {
            $value = call_user_func($callback, $key, $value);
        });
    
        if (!$result)
            return false;
    
        return $arr;
    }
    

    Example:

    $test_array = array("first_key" => "first_value", 
                    "second_key" => "second_value");
    
    var_dump(array_map_(function($key, $value){
        return $key . " loves " . $value;
    }, $arr));
    

    Output:

    array (
      'first_key' => 'first_key loves first_value,
      'second_key' => 'second_key loves second_value',
    )
    

    Off course, you can use array_values to return exactly what OP wants.

    array_values(array_map_(function($key, $value){
        return $key . " loves " . $value;
    }, $test_array))
    
    0 讨论(0)
  • 2020-11-30 20:03

    A closure would work if you only need it once. I'd use a generator.

    $test_array = [
        "first_key" => "first_value", 
        "second_key" => "second_value",
    ];
    
    $x_result = (function(array $arr) {
        foreach ($arr as $key => $value) {
            yield "$key loves $value";
        }
    })($test_array);
    
    var_dump(iterator_to_array($x_result));
    
    // array(2) {
    //   [0]=>
    //   string(27) "first_key loves first_value"
    //   [1]=>
    //   string(29) "second_key loves second_value"
    // }
    

    For something reusable:

    function xmap(callable $cb, array $arr)
    {
        foreach ($arr as $key => $value) {
            yield $cb($key, $value);
        }
    }
    
    var_dump(iterator_to_array(
        xmap(function($a, $b) { return "$a loves $b"; }, $test_array)
    ));
    
    0 讨论(0)
提交回复
热议问题