有没有这样做的方法:

$test_array = array(
    "first_key" => "first_value", 
    "second_key" => "second_value"
);

var_dump(
    array_map(
        function($a, $b) {
            return "$a loves $b";
        }, 
        array_keys($test_array), 
        array_values($test_array)
    )
);

但是不是调用array_keys和array_values,而是直接传递$test_array变量?

期望的输出是:

array(2) {
  [0]=>
  string(27) "first_key loves first_value"
  [1]=>
  string(29) "second_key loves second_value"
}

当前回答

如果你只需要它一次,闭包就可以了。我会用发电机。

$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"
// }

对于可重复使用的东西:

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)
));

其他回答

我将使用5.6或更高版本为该问题添加另一个解决方案。不知道它是否比已经很棒的解决方案更有效(可能不是),但对我来说,它只是更容易阅读:

$myArray = [
    "key0" => 0,
    "key1" => 1,
    "key2" => 2
];

array_combine(
    array_keys($myArray),
    array_map(
        function ($intVal) {
            return strval($intVal);
        },
        $myArray
    )
);

使用strval()作为array_map中的示例函数,这将生成:

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

希望我不是唯一一个觉得这个很容易理解的人。 Array_combine从一个键数组和一个值数组中创建了一个key =>值数组,剩下的是不言自明的。

我会这样做:

<?php

/**
 * array_map_kv()
 *   An array mapping function to map with both keys and values.
 *
 * @param $callback callable
 *   A callback function($key, $value) for mapping values.
 * @param $array array
 *   An array for mapping.
 */
function array_map_kv(callable $callback, array $array) {
  return array_map(
    function ($key) use ($callback, $array) {
      return $callback($key, $array[$key]); // $callback($key, $value)
    },
    array_keys($array)
  );
}

// use it
var_dump(array_map_kv(function ($key, $value) {
  return "{$key} loves {$value}";
}, array(
  "first_key" => "first_value",
  "second_key" => "second_value",
)));

?>

结果:

array(2) {
  [0]=>
  string(27) "first_key loves first_value"
  [1]=>
  string(29) "second_key loves second_value"
}

不是array_map,因为它不处理键。

array_walk:

$test_array = array("first_key" => "first_value",
                    "second_key" => "second_value");
array_walk($test_array, function(&$a, $b) { $a = "$b loves $a"; });
var_dump($test_array);

// array(2) {
//   ["first_key"]=>
//   string(27) "first_key loves first_value"
//   ["second_key"]=>
//   string(29) "second_key loves second_value"
// }

然而,它确实会改变作为参数给出的数组,所以它不是确切的函数式编程(因为你有这样的问题标记)。此外,正如评论中指出的那样,这只会改变数组的值,因此键不会是您在问题中指定的键。

如果你想,你可以写一个函数来固定上面的点,像这样:

function mymapper($arrayparam, $valuecallback) {
  $resultarr = array();
  foreach ($arrayparam as $key => $value) {
    $resultarr[] = $valuecallback($key, $value);
  }
  return $resultarr;
}

$test_array = array("first_key" => "first_value",
                    "second_key" => "second_value");
$new_array = mymapper($test_array, function($a, $b) { return "$a loves $b"; });
var_dump($new_array);

// array(2) {
//   [0]=>
//   string(27) "first_key loves first_value"
//   [1]=>
//   string(29) "second_key loves second_value"
// }

用(out)保存键的另一种方法:

$test_array = [
    "first_key"     => "first_value",
    "second_key"    => "second_value"
];

$f = function($ar) {
    return array_map(
        function($key, $val) {
            return "{$key} - {$val}";
        },
        array_keys($ar),
        $ar
    );
};

#-- WITHOUT preserving keys
$res = $f($test_array);

#-- WITH preserving keys
$res = array_combine(
    array_keys($test_array),
    $f($test_array)
);

YaLinqo库*非常适合这类任务。它是。net的LINQ的一个端口,完全支持所有回调中的值和键,类似于SQL。例如:

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

或者是:

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

这里,“$k爱$v”是这个库支持的完全闭包语法的快捷方式。最后的toArray()是可选的。方法链返回一个迭代器,因此如果结果只需要使用foreach迭代,则可以删除toArray调用。

*由我开发