PHP:我可以在 array_map 函数中获取索引吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5868457/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 22:44:27  来源:igfitidea点击:

PHP: Can I get the index in an array_map function?

phparraysloopsdictionaryiteration

提问by Ollie Glass

I'm using a map in php like so:

我在 php 中使用地图,如下所示:

function func($v) {
    return $v * 2;
}

$values = array(4, 6, 3);
$mapped = array_map(func, $values);
var_dump($mapped);

Is it possible to get the index of the value in the function?

是否可以获取函数中值的索引?

Also - if I'm writing code that needs the index, should I be using a for loop instead of a map?

另外 - 如果我正在编写需要索引的代码,我应该使用 for 循环而不是地图吗?

回答by Aron Rotteveel

Sure you can, with the help of array_keys():

当然可以,在帮助下 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);

回答by Warbo

When mapping an anonymous function over an anonymous array, there is no way to access the keys:

在匿名数组上映射匿名函数时,无法访问键:

array_map(
    function($val) use ($foo) { /* ... */ },
    array(key1 => val1,
          key2 => val2,
          /* ... */));

array_reduce doesn't get access to the keys either. array_walk can access keys, but the array is passed by reference, which requires a layer of indirection.

array_reduce 也无法访问密钥。array_walk 可以访问键,但是数组是通过引用传递的,需要一层间接。

Some solutions are:

一些解决方案是:

Array of pairs

对数组

This is bad, since we're changing the original array. Plus the boilerplate "array()" calls increase linearly with the length of the array:

这很糟糕,因为我们正在更改原始数组。加上样板“array()”调用随着数组的长度线性增加:

array_map(
    function($pair) use ($foo) {
        list($key, $val) = $pair;
        /* ... */
    },
    array(array(key1, val1),
          array(key2, val2),
          /* ... */));

Temporary variable

临时变量

We're acting on the original array, and the boilerplate is constant, but we can easily clobber an existing variable:

我们对原始数组进行操作,样板文件是常量,但我们可以轻松破坏现有变量:

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

One-shot function

一键功能

We can use function scope to prevent clobbering existing names, but have to add an extra layer of "use":

我们可以使用函数作用域来防止破坏现有名称,但必须添加一个额外的“使用”层:

call_user_func(
    function($arr) use ($foo) {
        return array_map(function($key, $val) use ($foo) { /* ... */ },
                         array_keys($arr),
                         $arr);
    },
    array(key1 => val1,
          key2 => val2,
          /* ... */));

Multi-argument one-shot function

多参数一次性功能

We define the function we're mapping in the original scope to prevent the "use" boilerplate):

我们定义了我们在原始范围内映射的函数以防止“使用”样板):

call_user_func(
    function($f, $arr) {
        return array_map($f, array_keys($arr), $arr);
    },
    function($key, $val) use ($foo) { /* ... */ },
    array(key1 => val1,
          key2 => val2,
          /* ... */));

New function

新功能

The interesting thing to note is that our last one-shot function has a nice, generic signature and looks a lot like array_map. We might want to give this a name and re-use it:

有趣的是,我们的最后一个一次性函数有一个很好的通用签名,看起来很像 array_map。我们可能想给它一个名字并重新使用它:

function array_mapk($f, $arr) {
    return array_map($f, array_keys($arr), $arr);
}

Our application code then becomes:

然后我们的应用程序代码变为:

array_mapk(
    function($key, $val) use ($foo) { /* ... */ },
    array(key1 => val1,
          key2 => val2,
          /* ... */));

Indirect Array Walk

间接数组遍历

When writing the above I'd ignored array_walk since it requires its argument to be passed by reference; however, I've since realised that it's easy to work around this using call_user_func. I think this is the best version so far:

在编写上述内容时,我忽略了 array_walk,因为它需要通过引用传递其参数;然而,我后来意识到使用 call_user_func 很容易解决这个问题。我认为这是迄今为止最好的版本:

call_user_func(
    'array_walk',
    array(key1 => val1,
          key2 => val2,
          /* ... */),
    function($val, $key) use ($foo) { /* ... */ });

回答by Fábio Zangirolami

Very simple:

很简单:

Only array_map fuction: does not have index key!

只有 array_map 功能:没有索引键!

 $params = [4,6,2,11,20];

 $data = array_map(function($v) { return ":id{$v}";}, $params);

 array (size=5)
  0 => string ':id4' (length=4)
  1 => string ':id6' (length=4)
  2 => string ':id2' (length=4)
  3 => string ':id11' (length=5)
  4 => string ':id20' (length=5)

Now, combine with array_keys:

现在,结合 array_keys:

$data = array_map(
    function($k) use ($params) { return ":id{$k}_${params[$k]}"; },
    array_keys($params)
 );

array (size=5)
  0 => string ':id0_4' (length=6)
  1 => string ':id1_6' (length=6)
  2 => string ':id2_2' (length=6)
  3 => string ':id3_11' (length=7)
  4 => string ':id4_20' (length=7)