Oll*_*ass 62 php arrays iteration dictionary loops
我在php中使用地图如下:
function func($v) {
return $v * 2;
}
$values = array(4, 6, 3);
$mapped = array_map(func, $values);
var_dump($mapped);
Run Code Online (Sandbox Code Playgroud)
是否有可能获得函数中值的索引?
另外 - 如果我正在编写需要索引的代码,我应该使用for循环而不是map吗?
Aro*_*eel 172
当然,你可以在...的帮助下 array_keys():
function func($v, $k) {
// key is now $k
return $v * 2;
}
$values = array(4, 6, 3);
$mapped = array_map(func, $values, array_keys($values));
var_dump($mapped);
Run Code Online (Sandbox Code Playgroud)
Eva*_*van 13
无法在array_map
回调中访问索引。如果您使用顺序数字索引,则可以使用递增静态变量:
$values = ["one", "two", "three"];
$mapped = array_map(function ($value) {
static $i = 0;
$result = "Index: $i, Value: $value";
$i++;
return $result;
}, $values);
print_r($mapped);
Run Code Online (Sandbox Code Playgroud)
导致:
Array
(
[0] => Index: 0, Value: one
[1] => Index: 1, Value: two
[2] => Index: 2, Value: three
)
Run Code Online (Sandbox Code Playgroud)
使用此方法时,重要的是使用匿名函数作为回调,并且永远不要重用该匿名函数,以避免引用 array_map 外部的相同静态变量。
在匿名数组上映射匿名函数时,无法访问密钥:
array_map(
function($val) use ($foo) { /* ... */ },
array(key1 => val1,
key2 => val2,
/* ... */));
Run Code Online (Sandbox Code Playgroud)
array_reduce也无法访问密钥.array_walk可以访问键,但是数组是通过引用传递的,这需要一层间接.
一些解决方案是:
这很糟糕,因为我们正在更改原始数组.此外,样板"array()"调用随着数组的长度线性增加:
array_map(
function($pair) use ($foo) {
list($key, $val) = $pair;
/* ... */
},
array(array(key1, val1),
array(key2, val2),
/* ... */));
Run Code Online (Sandbox Code Playgroud)
我们正在对原始数组进行操作,并且样板文件是常量,但我们可以轻松地破坏现有变量:
$i_hope_this_does_not_conflict = array(key1 => val1,
key2 => val2,
/* ... */);
array_map(
function($key, $val) use ($foo) { /* ... */ },
array_keys($i_hope_this_does_not_conflict),
$i_hope_this_does_not_conflict);
unset($i_hope_this_does_not_conflict);
Run Code Online (Sandbox Code Playgroud)
我们可以使用函数范围来防止破坏现有名称,但必须添加额外的"使用"层:
call_user_func(
function($arr) use ($foo) {
return array_map(function($key, $val) use ($foo) { /* ... */ },
array_keys($arr),
$arr);
},
array(key1 => val1,
key2 => val2,
/* ... */));
Run Code Online (Sandbox Code Playgroud)
我们定义了我们在原始范围内映射的函数,以防止"使用"样板:
call_user_func(
function($f, $arr) {
return array_map($f, array_keys($arr), $arr);
},
function($key, $val) use ($foo) { /* ... */ },
array(key1 => val1,
key2 => val2,
/* ... */));
Run Code Online (Sandbox Code Playgroud)
有趣的是要注意的是,我们的最后一次性功能有一个很好的通用签名,看起来很像array_map.我们可能想给它一个名字并重复使用它:
function array_mapk($f, $arr) {
return array_map($f, array_keys($arr), $arr);
}
Run Code Online (Sandbox Code Playgroud)
我们的应用程序代码变为:
array_mapk(
function($key, $val) use ($foo) { /* ... */ },
array(key1 => val1,
key2 => val2,
/* ... */));
Run Code Online (Sandbox Code Playgroud)
写上面的时候我忽略了array_walk,因为它要求它的参数通过引用传递; 但是,我已经意识到使用call_user_func很容易解决这个问题.我认为这是目前为止最好的版本:
call_user_func(
'array_walk',
array(key1 => val1,
key2 => val2,
/* ... */),
function($val, $key) use ($foo) { /* ... */ });
Run Code Online (Sandbox Code Playgroud)
小智 5
这是一个有点旧的线程,但和你们中的许多人一样,我正在使用array_keys
:
array_map(function($id, $name) {
print '<option value="'.$id.'">'.$name.'</option>';
}, array_keys($array), array_values($array));
Run Code Online (Sandbox Code Playgroud)
编辑:use
您可以在函数的第二个参数中添加两个数组,而不是关键字arrray_map
。我认为不需要解释,代码非常简单。