私は次のようにphpでマップを使用しています:
function func($v) {
return $v * 2;
}
$values = array(4, 6, 3);
$mapped = array_map(func, $values);
var_dump($mapped);
関数内の値のインデックスを取得することは可能ですか?
また、インデックスが必要なコードを書いている場合、マップの代わりにforループを使用する必要がありますか?
私は次のようにphpでマップを使用しています:
function func($v) {
return $v * 2;
}
$values = array(4, 6, 3);
$mapped = array_map(func, $values);
var_dump($mapped);
関数内の値のインデックスを取得することは可能ですか?
また、インデックスが必要なコードを書いている場合、マップの代わりにforループを使用する必要がありますか?
回答:
確かに、の助けを借りて、あなたはできる 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);
array_map()
、任意の数の引数を指定できます:)
array_keys
が元の配列と同じ順序のままであることを保証しないため、これは非常に危険なアプローチです。したがって、キーを間違った値にマッピングしてしまう可能性があります。安全なアプローチはarray_keys
、の2番目の引数としてのみ使用array_map
し、use
ステートメントを使用して配列をクロージャに渡すことです。
匿名配列に無名関数をマッピングする場合、キーにアクセスする方法はありません。
array_map(
function($val) use ($foo) { /* ... */ },
array(key1 => val1,
key2 => val2,
/* ... */));
array_reduceもキーにアクセスできません。array_walkはキーにアクセスできますが、配列は参照によって渡されるため、間接層が必要です。
いくつかの解決策は次のとおりです。
元の配列を変更しているので、これは悪いことです。さらに、ボイラープレートの「array()」呼び出しは、配列の長さに比例して増加します。
array_map(
function($pair) use ($foo) {
list($key, $val) = $pair;
/* ... */
},
array(array(key1, val1),
array(key2, val2),
/* ... */));
元の配列を操作しており、ボイラープレートは一定ですが、既存の変数を簡単に壊すことができます。
$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);
関数スコープを使用して既存の名前が壊れるのを防ぐことができますが、「使用」のレイヤーを追加する必要があります。
call_user_func(
function($arr) use ($foo) {
return array_map(function($key, $val) use ($foo) { /* ... */ },
array_keys($arr),
$arr);
},
array(key1 => val1,
key2 => val2,
/* ... */));
「使用」ボイラープレートを防ぐために、マッピングする関数を元のスコープで定義します)。
call_user_func(
function($f, $arr) {
return array_map($f, array_keys($arr), $arr);
},
function($key, $val) use ($foo) { /* ... */ },
array(key1 => val1,
key2 => val2,
/* ... */));
注意すべき興味深い点は、最後のワンショット関数には優れた汎用シグネチャがあり、array_mapによく似ていることです。これに名前を付けて再利用したい場合があります。
function array_mapk($f, $arr) {
return array_map($f, array_keys($arr), $arr);
}
アプリケーションコードは次のようになります。
array_mapk(
function($key, $val) use ($foo) { /* ... */ },
array(key1 => val1,
key2 => val2,
/* ... */));
上記を書くとき、引数を参照で渡す必要があるため、array_walkは無視しました。ただし、call_user_funcを使用してこれを回避するのは簡単であることに気づきました。これはこれまでで最高のバージョンだと思います。
call_user_func(
'array_walk',
array(key1 => val1,
key2 => val2,
/* ... */),
function($val, $key) use ($foo) { /* ... */ });
非常に簡単:
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)
次に、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)