Khi ánh xạ một hàm ẩn danh qua một mảng ẩn danh, không có cách nào để truy cập các khóa:
array_map(
function($val) use ($foo) { },
array(key1 => val1,
key2 => val2,
));
array_reduce cũng không có quyền truy cập vào các khóa. array_walk có thể truy cập các khóa, nhưng mảng được truyền bởi tham chiếu, điều này yêu cầu một lớp hướng dẫn.
Một số giải pháp là:
Mảng các cặp
Điều này thật tệ, vì chúng tôi đang thay đổi mảng ban đầu. Cộng với các lệnh gọi "array ()" của bảng soạn sẵn sẽ tăng tuyến tính với độ dài của mảng:
array_map(
function($pair) use ($foo) {
list($key, $val) = $pair;
},
array(array(key1, val1),
array(key2, val2),
));
Biến tạm thời
Chúng tôi đang hành động trên mảng ban đầu và bảng soạn sẵn là không đổi, nhưng chúng tôi có thể dễ dàng chặn một biến hiện có:
$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);
Chức năng chụp một lần
Chúng tôi có thể sử dụng phạm vi chức năng để ngăn chặn các tên hiện có, nhưng phải thêm một lớp bổ sung "sử dụng":
call_user_func(
function($arr) use ($foo) {
return array_map(function($key, $val) use ($foo) { },
array_keys($arr),
$arr);
},
array(key1 => val1,
key2 => val2,
));
Chức năng một lần nhiều đối số
Chúng tôi xác định chức năng mà chúng tôi đang ánh xạ trong phạm vi ban đầu để ngăn chặn bảng soạn sẵn "sử dụng"):
call_user_func(
function($f, $arr) {
return array_map($f, array_keys($arr), $arr);
},
function($key, $val) use ($foo) { },
array(key1 => val1,
key2 => val2,
));
Chức năng mới
Điều thú vị cần lưu ý là hàm one-shot cuối cùng của chúng ta có một chữ ký chung, đẹp và trông rất giống với array_map. Chúng tôi có thể muốn đặt tên này và sử dụng lại nó:
function array_mapk($f, $arr) {
return array_map($f, array_keys($arr), $arr);
}
Mã ứng dụng của chúng tôi sau đó trở thành:
array_mapk(
function($key, $val) use ($foo) { },
array(key1 => val1,
key2 => val2,
));
Đi bộ theo mảng gián tiếp
Khi viết phần trên, tôi đã bỏ qua array_walk vì nó yêu cầu đối số của nó phải được truyền bằng tham chiếu; tuy nhiên, tôi đã nhận ra rằng thật dễ dàng để giải quyết vấn đề này bằng cách sử dụng call_user_func. Tôi nghĩ đây là phiên bản tốt nhất cho đến nay:
call_user_func(
'array_walk',
array(key1 => val1,
key2 => val2,
),
function($val, $key) use ($foo) { });