有没有这样做的方法:

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

其他回答

我所说的“手动循环”是指编写一个使用foreach的自定义函数。它像array_map一样返回一个新数组,因为函数的作用域导致$array是一个复制,而不是一个引用:

function map($array, callable $fn) {
  foreach ($array as $k => &$v) $v = call_user_func($fn, $k, $v);
  return $array;
}

你使用array_map和array_keys的技术实际上看起来更简单,也更强大,因为你可以使用null作为回调来返回键值对:

function map($array, callable $fn = null) {
  return array_map($fn, array_keys($array), $array);
}

我一直喜欢数组映射的javascript变体。最简单的版本是:

/**
 * @param  array    $array
 * @param  callable $callback
 * @return array
 */
function arrayMap(array $array, callable $callback)
{
    $newArray = [];

    foreach( $array as $key => $value )
    {
        $newArray[] = call_user_func($callback, $value, $key, $array);
    }

    return $newArray;
}

现在你可以给它一个回调函数如何构造值。

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

var_dump(
    arrayMap($testArray, function($value, $key) {
        return $key . ' loves ' . $value;
    });
);

我将使用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 =>值数组,剩下的是不言自明的。

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调用。

*由我开发

PHP5.3或更高版本:

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

var_dump(
    array_map(
        function($key) use ($test_array) { return "$key loves ${test_array[$key]}"; },
        array_keys($test_array)
    )
);