İşte benim çok basit, PHP 5.5 uyumlu çözümüm:
function array_map_assoc(callable $f, array $a) {
return array_column(array_map($f, array_keys($a), $a), 1, 0);
}
Sağladığınız çağrılabilirin kendisi iki değere sahip bir dizi döndürmelidir return [key, value]. Bu array_mapnedenle iç çağrı , bir dizi dizi üretir. Bu daha sonra tarafından tek boyutlu bir diziye geri dönüştürülür array_column.
kullanım
$ordinals = [
'first' => '1st',
'second' => '2nd',
'third' => '3rd',
];
$func = function ($k, $v) {
return ['new ' . $k, 'new ' . $v];
};
var_dump(array_map_assoc($func, $ordinals));
Çıktı
array(3) {
["new first"]=>
string(7) "new 1st"
["new second"]=>
string(7) "new 2nd"
["new third"]=>
string(7) "new 3rd"
}
Kısmi uygulama
İşlevi farklı dizilerle ancak aynı eşleme işleviyle birçok kez kullanmanız gerekirse, yalnızca çağırma üzerine veri dizisine geçmenize izin veren kısmi işlev uygulaması (' currying ' ile ilgili) olarak adlandırılan bir şey yapabilirsiniz :
function array_map_assoc_partial(callable $f) {
return function (array $a) use ($f) {
return array_column(array_map($f, array_keys($a), $a), 1, 0);
};
}
...
$my_mapping = array_map_assoc_partial($func);
var_dump($my_mapping($ordinals));
Hangi aynı çıktıyı verir, verilen $funcve $ordinalsdaha önceki gibi.
NOT: eşlenen işleviniz iki farklı giriş için aynı anahtarı döndürürse , sonraki anahtarla ilişkili değer kazanacaktır. array_map_assocDaha önceki anahtarların kazanmasına izin vermek için giriş dizisini ve çıkış sonucunu tersine çevirin . (Örneğimdeki döndürülen anahtarlar, kaynak dizinin anahtarını içerdiklerinden çakışamazlar; bu da benzersiz olmalıdır.)
Alternatif
Aşağıda, bazıları için daha mantıklı olabilecek, ancak PHP 5.6 gerektiren bir varyant yer almaktadır:
function array_map_assoc(callable $f, array $a) {
return array_merge(...array_map($f, array_keys($a), $a));
}
Bu varyantta, sağladığınız işlev (üzerinde veri dizisinin eşlendiği), bunun yerine bir satırla ilişkilendirilebilir bir dizi döndürmelidir return [key => value]. Çağrılabilir eşlemenin sonucu daha sonra paketten çıkarılır ve iletilir array_merge. Daha önce olduğu gibi, yinelenen bir anahtarın döndürülmesi sonraki değerlerin kazanılmasına neden olacaktır.
nb Alex83690 bir yorumda, array_replacebunun yerine burada array_mergetamsayı anahtarlarının korunacağını belirtti. array_replacegiriş dizisini değiştirmez, bu nedenle işlevsel kod için güvenlidir.
PHP 5.3 ile 5.5 arasındaysanız, aşağıdakine denktir. Anahtarları korurken elde edilen iki boyutlu diziyi tek boyutlu bir diziye dönüştürmek için array_reduceve ikili +dizi operatörünü kullanır :
function array_map_assoc(callable $f, array $a) {
return array_reduce(array_map($f, array_keys($a), $a), function (array $acc, array $a) {
return $acc + $a;
}, []);
}
kullanım
Bu değişkenlerin her ikisi de şu şekilde kullanılır:
$ordinals = [
'first' => '1st',
'second' => '2nd',
'third' => '3rd',
];
$func = function ($k, $v) {
return ['new ' . $k => 'new ' . $v];
};
var_dump(array_map_assoc($func, $ordinals));
Not =>yerine ,de $func.
Çıktı öncekiyle aynıdır ve her biri eskisi gibi kısmen uygulanabilir.
özet
Orijinal sorunun amacı, çağrının çağrılmasını mümkün olduğunca basit hale getirmek ve çağrılmış daha karmaşık bir işleve sahip olmaktır; özellikle, veri dizisini anahtarları ve değerleri bölmeden tek bir argüman olarak iletme yeteneğine sahip olmak. Bu cevabın başında verilen işlevi kullanarak:
$test_array = ["first_key" => "first_value",
"second_key" => "second_value"];
$array_map_assoc = function (callable $f, array $a) {
return array_column(array_map($f, array_keys($a), $a), 1, 0);
};
$f = function ($key, $value) {
return [$key, $key . ' loves ' . $value];
};
var_dump(array_values($array_map_assoc($f, $test_array)));
Veya yalnızca bu soru için, array_map_assoc()çıkış anahtarları bırakan işlev için basitleştirme yapabiliriz , çünkü soru bunları sormaz:
$test_array = ["first_key" => "first_value",
"second_key" => "second_value"];
$array_map_assoc = function (callable $f, array $a) {
return array_map($f, array_keys($a), $a);
};
$f = function ($key, $value) {
return $key . ' loves ' . $value;
};
var_dump($array_map_assoc($f, $test_array));
Yani cevap HAYIR , aramaktan kaçınamazsınız array_keys, ancak array_keysyeterince iyi olabilecek daha üst düzey bir fonksiyona çağrılan yeri soyutlayabilirsiniz .